参考boyn博言 极光雨雨等博客内容

Function简介

在函数式编程中,我们用的最多的往往是Function接口.通常来说,我们很少会直接使用这个接口,但是在Java的函数式编程中,许多组件都会与这个接口有关.需要注意的是,很多人会混淆Java8中新增的Stream API与函数式编程的概念,事实上,Stream API是一种为了实现自动化并行的惰性求值的解决方法,与函数式没有太大关系,但是其与函数式编程结合会很好用.

0.源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package java.util.function;  

import java.util.Objects;

@FunctionalInterface
public interface Function<T, R> {

R apply(T t);

default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}

static <T> Function<T, T> identity() {
return t -> t;
}
}

1.apply

apply 的作用为执行当前方法函数,t 为入参,R 为返回值类型

示例代码

1
2
3
4
5
6
7
8
9
        Function<Integer, String> function1 = item -> {
item *= 100;
return item + "";
};

String apply = function1.apply(13);
System.out.println("apply = " + apply);

result: apply = 1300

2.compose

compose 看内部实现,这个方法的入参也为 Function 类型,当调用时会先执行 作为入参的 Function 中的apply 方法,再将计算的结果作为原有方法的 apply 入参

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        //第一个方法函数
Function<Integer, String> function1 = item -> {
item *= 100;
return item + "";
};

String apply = function1.apply(13);
System.out.println("apply = " + apply);

// 定义的第二个方法函数
Function<Integer, Integer> function2 = item -> item + 10;
// 先将 13 作为function2的入参 然后将结果作为function1的入参继续计算
String apply2 = function1.compose(function2).apply(13);
System.out.println("apply2 = " + apply2);

result: apply = 1300
apply2 = 2300

3.andThen

andThen 与compose 类似,但是方向相反,调用时会后执行

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
        //定义第一个方法函数
Function<Integer, String> function1 = item -> {
item *= 100;
return item + "";
};

String apply = function1.apply(13);
System.out.println("apply = " + apply);

// 定义的第二个方法函数
Function<Integer, Integer> function2 = item -> item + 10;
// 先将 13 作为function2的入参 然后将结果作为function1的入参继续计算
String apply2 = function1.compose(function2).apply(13);
System.out.println("apply2 = " + apply2);

// 定义的第三个方法函数
Function<String, Integer> function3 = item -> Integer.valueOf(item) + 31;
// 先将 13 作为function1的入参 然后将结果作为function3的入参继续计算
Integer apply3 = function1.andThen(function3).apply(13);
System.out.println("apply3 = " + apply3);

result: apply = 1300
apply2 = 2300
apply3 = 1331


4.identity

Function.identity()返回一个输出跟输入一样的Lambda表达式对象,等价于形如t -> t形式的Lambda表达式

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public static void main(String[] args) {  
List<Person> personList = new ArrayList<>();
personList.add(new Person("hepengju", 28, 20000.0));
personList.add(new Person("lisi" , 44, 40000.0));
personList.add(new Person("wangwu" , 55, 50000.0));
personList.add(new Person("zhaoliu" , 66, 60000.0));
personList.add(new Person("zhangsan", 33, 33333.0));
personList.add(new Person("wgr", 23, 10000.0));

//该map键为name,值为Person对象,若改为x -> x.getName,nap值为name
Map<String, String> collect = personList.stream().collect(Collectors.toMap(Person::getName, Function.identity()));
collect.forEach((name,p) ->{
System.out.println(name + ":"+p.toString());
});

}

static class Person{
String name;
int age;
double money;

public Person(String name, int age, double money) {
this.name = name;
this.age = age;
this.money = money;
}

public String getName() {
return name;
}

@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + ", money=" + money + '}';
}
}