java可以像python中的函式式工具裡的reduce那樣呼叫嗎?

趙年峰發表於2013-01-28

函式式工具(一) - java可以像python中的函式式工具裡的reduce那樣呼叫嗎?

python 裡這樣寫,在java裡是否也能這樣寫嗎?

reduce(add, range(1, 11))
reduce(max,[11,-25])

能!

首先我們實現reduce這個函式。當然不可能事先全,因為java全處理的話,需要很長的程式碼,我們這裡暫時只舉3個例子。

class ob{
    @SuppressWarnings("unchecked")

    public static <T> T reduce(Class c , String m , T ... objects  ) {
        for ( Method tm :c.getDeclaredMethods() ){
            if( m.equals(tm.getName() ) ){
                if (tm.getParameterTypes().length == 1){
                    if ( tm.getParameterTypes()[0].isArray() == true){
                        tm.setAccessible(true);
                        try {
                            T [] a = (T[]) new Object[1]; 
                            a[0] = (T) Arrays.asList(objects).toArray();
                            return (T) tm.invoke(null, a);
                        } catch (IllegalArgumentException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
                if ( objects.length ==  tm.getParameterTypes().length ){

                    /*個別引數查詢**/
                    for (int i = 0 ; i<tm.getParameterTypes().length;i++){
                        if (tm.getParameterTypes()[i]
                            .getSimpleName().toLowerCase().equals(

                            objects[i].getClass().
                            getSimpleName().toLowerCase() ) )
                        {
                            tm.setAccessible(true);
                            try {
                                return (T) tm.invoke(null, objects);
                            } catch (IllegalArgumentException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            } catch (IllegalAccessException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }


                }
            }
        }
        return null;
    }
}

首先一點,上面的類實現得不是非常完美,會在以後的文章中慢慢地重構和優化他。

因為Math物件中沒有add類,那麼我們自己建立一個MyMath物件。

class myMath{
    public static Integer add(Integer[] is){
        Integer result = 0;
        for (Integer a : is ){
            result += a;
        }
        return result;
    }

}

我們建立一個試驗函式吧!!。。激動人心的時刻到了:

List<Integer> x = Arrays.asList(1,2,3,4,5,6,7);

Integer c = (Integer) ob.reduce(myMath.class, "add", x.toArray());
System.out.println(c);

列印的結果為

28

OY! 我們成功了。

那麼我們建立的reduce函式也支援math中的大部分操作:

double b = ob.reduce(Math.class,"max",1.2,3.2);
System.out.println(b);

Double a = ob.reduce(Math.class,"abs",-2.2);
System.out.println(a);

例子程式碼如上。分別會列印出來 3.2和 2.2

這樣看起來我們的java程式是不是更加函式化了呢?當然對於xrange和range很好實現,這裡就不給出現了。

以下是使用range或者xrange的樣例程式碼。

Integer c = (Integer) ob.reduce(myMath.class, "add", range(1,7);

是不是有點函數語言程式設計的味道了?

哈哈

相關文章