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)。

相关文章
相关标签/搜索