函式式工具

趙年峰發表於2013-01-28

這裡會增加一些函式式的工具函式和類

java functional tools 工具包教程

java functional tools 教程

包的下載地址:戳進

感謝

感謝圖靈社群的@2gua 老師 在<<java可以像python中的函式式工具裡的reduce那樣呼叫嗎?>>的提醒!

前言

如果你玩過pythonic樣式的程式碼,如果你寫過函式式程式。那麼你卻在java陣營搞開發,整天需要寫很多的程式碼行來完成工作。你是不是感覺到很~很~很那個,你懂的

那麼這個工具會幫助你完成java的函式式程式碼。

首先我們先來了解一下如何使用和為什麼使用這個包。

章節 1

樣例程式碼 1

package demo;

import java.util.Arrays;
import java.util.List;

import functional.tools.f;
import functional.tools.operator;


public class demo1 {

    public static void main(String[] args) {
        //場景0
        double b = f.reduce(Math.class,"max",1,3);
        System.out.println(b);

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

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

        //場景1
        Integer e = (Integer) f.reduce(operator.class, "max", x.toArray());
        System.out.println(e);

        //場景2
        Integer c = (Integer) f.reduce(operator.class, "add", x.toArray());
        System.out.println(c);
        //場景3
        Integer d = (Integer) f.reduce(operator.class, "mul",x.toArray(),2);
        System.out.println(d);

        List<String> strs = Arrays.asList("1","hello","test","nihao");
        //場景4
        String r = (String) f.reduce(operator.class, "concat", strs.toArray());
        System.out.println(r);
    }

}

場景0提供了一些函式的回撥的方式的呼叫方法。


場景1 :找出列表中的最大值

一般情況下,我們求一個列表的max值,大部分都是這樣寫的。

List<Integer> x = Arrays.asList(1,2,3,4,5,6,7);
Integer t = 0 ;
for ( Integer i : x ){
    if (t <= i){
        t = i;
    }
}
System.out.println(t);

//使用排序的話是這樣
Integer [] arys = x.toArray();
Arrays.sort(arys);
System.out.println(arys[arys.length-1]);

首先我們不考慮和爭論演算法問題。僅僅從程式碼的行數就可以看到。上面的程式碼行數不夠精簡。那麼我們有足夠的理由讓他變成一句話。

Integer e = (Integer) f.reduce(operator.class, "max", x.toArray());
system.out.println(e);

場景2:對列表的數值進行求和

場景2和場景1情況差不多。同樣的java非函式式的程式碼如下:

List<Integer> x = Arrays.asList(1,2,3,4,5,6,7);
Integer t = 0 ;
for ( Integer i : x ){
    t += i;
}
System.out.println(t);

那麼我們的改善方案是這樣:

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

這樣寫不但十分好處理,當你需要分佈對x的結果統計的時候也十分好處理,因為你只需要對x拆分,然後分別呼叫如上程式碼,再彙總就可以。而不用考慮任何同步問題。


場景3:對列表中的數值進行求乘積

場景3和場景2幾乎一樣。這裡不給出非函式式程式碼。

那麼我們的改善方案是這樣:

Integer d = (Integer) f.reduce(operator.class, "mul",x.toArray(),2);
System.out.println(d);

注意:mul 這個函式只支援2個引數,第一個是陣列,第二個是一個數值

場景4:對列表中字串進行拼接

場景4給出的方案如下:

List<String> strs = Arrays.asList("1","hello","test","nihao");
//場景4
String r = (String) f.reduce(operator.class, "concat", strs.toArray());
System.out.println(r);

以上4個場景主要是為了讓程式碼看上去更整潔和在併發處理的時候,不會考慮同步問題。

以後java functional tools這個程式包還會增加更多的有用的簡潔的工具函式和樣例程式碼。

java functional tools 教程-loop函式

java functional tools 教程

jfunctional 程式碼下載地址的下載地址:戳進

章節2

這一節,不貼大段的程式碼了。直接講應用場景吧。

首先給定一個列表 x

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

場景1:需求程式碼,增加一個列表和若干常量,並列印出他們。

List<Integer> t = new ArrayList<Integer>();
t.addAll(x);
t.add(9);
t.add(8);
t.add(9);

for ( Integer a : t){
    System.out.println(a);
}

如上程式碼,我們可以看到首先建立一個新列表t,然後把 x,9,8,9 這些變數和常量增加到列表t中。

那麼我們使用jfunctional怎麼來解決呢?

final ArrayList<Integer> less2 = new ArrayList<Integer>();
f.loop( new function<Integer>(){
    @Override
    public <T> T lambda(T... t) {
        System.out.println(t[0]);
        return null;
    }
} , x,9,8,9);

我們可以這樣來解決.這樣還看不出來優美與否。那麼我們如果是不止9,8,9這3個常量呢?

比如一共要增加:

x,9,8,9,2,1,2,3,12,2,2,2

那麼需求程式碼會變的非常大,非常長!

如果使用jfunctional只需要這樣:

final ArrayList<Integer> less2 = new ArrayList<Integer>();
f.loop( new function<Integer>(){
    @Override
    public <T> T lambda(T... t) {
        System.out.println(t[0]);
        return null;
    }
} , x,9,8,9,2,1,2,3,12,2,2,2);

java functional tools 教程-lambda表示式

java functional tools 教程

jfunctional 程式碼下載地址的下載地址:戳進

章節3

這一節我們來講一下如何使用lambda,沒聽錯。老版本的jdk依然可以使用匿名函式模仿lambda,其實我們在章節2中已經使用了lambda表示式的寫法。

場景1,求一個列表和,並列印出他們.

System.out.println(
    new function(){
        @Override
        public Object lambda(Object... t) {
            return f.reduce(operator.class, "add", ( (Collection)t[0] ).toArray() );
        }
}.lambda(x) );

如果一行內寫出來。也是可能的。

System.out.println( f.reduce(operator.class, "add", x.toArray() ) );

這裡用到了我們前面講解的f.reduceoperator.add這兩個static class method

場景2 , 求一個列表乘積再乘2,並列印出他們

System.out.println(
    new function(){
        @Override
        public Object lambda(Object... t) {
            return f.reduce(operator.class, "mul", ( (Collection)t[0] ).toArray() , 2 );
        }    
}.lambda(x) );

一行程式碼寫出的方法同上呼叫mul。

增加lambda元素是為了以後更好的在一段長表示式中增加傳值過程,這樣確保以後更多的類似loop這樣的static class method可以更好的,更優美的呼叫其他函式。

相關文章