JDK8學習筆記-Function接口

學習JDK8新特性,必不可少的就是函數式編程,那也就不得不瞭解Function接口的使用了。java

首先看下Function接口的定義編程

@FunctionalInterface
public interface Function<T, R>{
	/**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);
	
	// 省略其餘方法
}

接口定義了兩個泛型,在使用的時候須要指定。app

該接口中比較重要的就是這個apply方法,其參數是類型T,返回時類型R(可能這麼描述不太合適)函數式編程

接下來看下Map中的新方法(該方法的詳解能夠參考個人另外一篇博客https://my.oschina.net/simpleton/blog/1552737函數

default V computeIfAbsent(K key,
        Function<? super K, ? extends V> mappingFunction) {
    Objects.requireNonNull(mappingFunction);
    V v;
    if ((v = get(key)) == null) {
        V newValue;
        if ((newValue = mappingFunction.apply(key)) != null) {
            put(key, newValue);
            return newValue;
        }
    }

    return v;
}

這個方法第一個參數是Map的key,第二個參數就是一個函數接口,在該方法內部調用了apply(key)。學習

好的,咱們來看看如何使用這個方法ui

String[] data = "1 2 3 4 1 2 3 1 2 1".split(" ");

HashMap<String, LinkedList<String>> map1 = new HashMap<>();
for (String s : data) {
   map1.computeIfAbsent(s, s1 -> new LinkedList<>()).add(s);
}
System.out.println("map1 = " + map1);

上面方法的輸出結果以下:this

map1 = {1=[1, 1, 1, 1], 2=[2, 2, 2], 3=[3, 3], 4=[4]}.net

說明下這段代碼code

map1.computeIfAbsent(s, s1 -> new LinkedList<>()).add(s);

map1對象調用computeIfAbsent方法,傳入了2個參數,s是map1中的key,第二個是一段函數定義,s1是函數的參數,new LinkedList<>()是函數的實現,實際上這是一個縮寫,完整寫法以下

map1.computeIfAbsent(s, (s1) -> {return new LinkedList<>();}).add(s);

對於只有一個參數的函數代碼,能夠省略(),即只須要寫s1,函數實現若是隻有一行代碼,能夠省略{}和return。

好了,而後就是computeIfAbsent內部的執行了,其實核心就是mappingFunction.apply(key),能夠看到,調用apply方法的時候,傳入的參數其實是key,也就是computeIfAbsent的第一個參數,那麼回過頭來看map1.computeIfAbsent(s, s1 -> new LinkedList<>()).add(s);這段代碼中的s和s1在函數代碼(s1 -> new LinkedList<>())運行的時候,其實s1的值就是s的值。很混亂是不?咱們再來看段代碼

String[] data = "1 2 3 4 1 2 3 1 2 1".split(" ");

HashMap<String, LinkedList<String>> map1 = new HashMap<>();
for (String s : data) {
   map1.computeIfAbsent(s, s1 -> {LinkedList list = new LinkedList<>();list.add(s1);return list;}).add(s);
   //map1.computeIfAbsent(s, s1 -> new LinkedList<String>()).add(s);
}
System.out.println("map1 = " + map1);

上面的輸出結果以下:

map1 = {1=[1, 1, 1, 1, 1], 2=[2, 2, 2, 2], 3=[3, 3, 3], 4=[4, 4]}

爲何呢?由於咱們定義的函數s1 -> {LinkedList list = new LinkedList<>();list.add(s1);return list;}實現中,將參數s1也放進了新建立的集合中。

 

到這裏,基本上已經說明了Function接口的如何在實際中使用了,另外還有BiFunction接口,其和Function接口的區別就是apply方法有兩個參數(我的的淺顯理解),還能夠本身定義符合本身業務須要的函數接口,具體定義方法,參考上述兩者便可。

在JDK8中,不少源代碼都用上了函數式編程,有興趣的話,能夠閱讀下相關源碼(推薦Map.java)。

相關文章
相關標籤/搜索