justry_deng
于 2019-09-16 15:12:53 发布
7807
收藏 33
分类专栏: jdk1.8特性 文章标签: Function函数 Function Function使用示例 Function介绍 JDK8特性
版权
jdk1.8特性
专栏收录该内容
8 篇文章8 订阅
订阅专栏
笔者日常: 来吧,Function~
相关声明:
本文按照以下顺序进行说明并给出简单的使用示例:
序号 接口
1 Function<T, R>
2 IntFunction<R>
3 DoubleFunction<R>
4 LongFunction<R>
5 ToIntFunction<T>
6 ToLongFunction<T>
7 ToDoubleFunction<T>
8 IntToDoubleFunction
9 IntToLongFunction
10 LongToDoubleFunction
11 LongToIntFunction
12 DoubleToIntFunction
13 DoubleToLongFunction
14 BiFunction<T, U, R>
15 ToIntBiFunction<T, U>
16 ToLongBiFunction<T, U>
17 ToDoubleBiFunction<T, U>
先给出下文的示例中所涉及到的模型:
/**
* 员工实体模型
*
* @author JustryDeng
* @date 2019/7/15 19:48
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Staff implements Serializable {
/** 姓名 */
private String name;
/** 年龄 */
private Integer age;
/** 工号 */
private String staffNo;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Function<T, R>:
R apply(T t): 输入T类型的参数,运行相关逻辑后,返回R类型的结果。
使用示例:
/**
* R apply(T t): 输入T类型的参数,运行相关逻辑后,返回R类型的结果。
*/
@Test
public void test1() {
Function<String, Staff> function = x -> {
Staff s = new Staff();
s.setName(x + ", 咿呀咿呀哟!");
return s;
};
Staff staff = function.apply("邓某");
// 输出: 邓某, 咿呀咿呀哟!
System.out.println(staff.getName());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Function<V, R> compose(Function<? super V, ? extends T> before): 由两个旧的Function得到一个新的Function。
假设: 现有式子functionC = functionB.compose(functionA),functionA 泛型为<P1, R1>, functionB泛型为<R1, R2>。
那么, 上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, R2>的functionC<P1, R2>。
使用示例:
/**
* <V> Function<V, R> compose(Function<? super V, ? extends T> before):由两个旧的Function得到一个新的Function。
*
* 假设:现有式子functionC = functionB.compose(functionA),
* functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
*
* 那么,上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值
* 作为functionB<R1, R2>的apply方法的入参,执行
* functionB<R1, R2>的apply方法,返回一个泛型为
* <P1, R2>的functionC<P1, R2>。
*/
@Test
public void test2() {
Function<String, Integer> functionA = x -> {
Objects.requireNonNull(x, "参数不能为空");
x = x.replace(" ", "");
return x.length();
};
Function<Integer, Staff> functionB = x -> {
Objects.requireNonNull(x, "参数不能为空");
Staff s = new Staff();
s.setAge(x);
return s;
};
Function<String, Staff> functionC = functionB.compose(functionA);
Staff staff = functionC.apply(" 我 是 参 数 ! ");
// 输出: Staff(name=null, age=5, staffNo=null)
System.out.println(staff);
}
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
Function<T, V> andThen(Function<? super R, ? extends V> after: 由两个旧的Function得到一个新的Function。
假设: 现有式子functionC = functionA.andThen(functionB),functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
那么, 上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, R2>的functionC<P1, R2>。
注: functionA.andThen(functionB)是先执行functionA,再执行functionB;而functionA.compose(functionB)是先执行functionB,再执行functionA。
使用示例:
/**
* <V> Function<T, V> andThen(Function<? super R, ? extends V> after):由两个旧的Function得到一个新的Function。
*
* 假设:现有式子functionC = functionA.andThen(functionB),
* functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
*
* 那么,上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值
* 作为functionB<R1, R2>的apply方法的入参,执行
* functionB<R1, R2>的apply方法,返回一个泛型为
* <P1, R2>的functionC<P1, R2>。
*
* 注: functionA.andThen(functionB)是先执行functionA,再执行functionB;
* 而functionA.compose(functionB)是先执行functionB,再执行functionA。
*/
@Test
public void test3() {
Function<String, Integer> functionA = x -> {
Objects.requireNonNull(x, "参数不能为空");
x = x.replace(" ", "");
return x.length();
};
Function<Integer, Staff> functionB = x -> {
Objects.requireNonNull(x, "参数不能为空");
Staff s = new Staff();
s.setAge(x);
return s;
};
Function<String, Staff> functionC = functionA.andThen(functionB);
Staff staff = functionC.apply(" 我 是 参 数 ! ");
// 输出: Staff(name=null, age=5, staffNo=null)
System.out.println(staff);
}
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
static Function<T, T> identity(): 将输入的参数进行返回,即: return t -> t。
注: 在某些情景下,使用Function.identity(),会让代码更优雅。
使用示例:
/**
* static <T> Function<T, T> identity(): 将输入的参数进行返回,即: return t -> t。
*
* 说明: 在某些情景下,使用Function.identity(),会让代码更优雅。
*/
@Test
public void test4() {
/*
* 使用普通的lambda表达式
*/
Map<Integer, String> mapOne = Stream.of("a", "ab", "abc", "abcd", "abcde").collect(
Collectors.toMap(String::length, param -> param)
);
// 输出: {1=a, 2=ab, 3=abc, 4=abcd, 5=abcde}
System.out.println(mapOne);
/*
* 使用Function.identity()无疑更优雅
*/
Map<Integer, String> mapTwo = Stream.of("a", "ab", "abc", "abcd", "abcde").collect(
Collectors.toMap(String::length, Function.identity())
);
// 输出: {1=a, 2=ab, 3=abc, 4=abcd, 5=abcde}
System.out.println(mapTwo);
}
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
IntFunction<R>:
R apply(int value): 入参类型必须为int, (运行相关逻辑后)返回R类型的数据。
使用示例:
/**
* R apply(int value): 入参类型必须为int, (运行相关逻辑后)返回R类型的数据。
*/
@Test
public void test5() {
IntFunction<Staff> intFunction = x -> {
Staff staff = new Staff();
staff.setAge(x);
return staff;
};
Staff res = intFunction.apply(100);
// 输出: Staff(name=null, age=100, staffNo=null)
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DoubleFunction<R>:
R apply(double value): 入参类型必须为double,(运行相关逻辑后)返回R类型的数据。
使用示例:
/**
* R apply(double value): 入参类型必须为double, (运行相关逻辑后)返回R类型的数据
*/
@Test
public void test6() {
DoubleFunction<String> doubleFunction = x -> (x + "").replace(".", "_");
String res = doubleFunction.apply(10.01);
// 输出: 10_01
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
LongFunction<R>:
R apply(long value): 入参类型必须为long, (运行相关逻辑后)返回R类型的数据。
使用示例:
/**
* R apply(long value): 入参类型必须为long, (运行相关逻辑后)返回R类型的数据。
*/
@Test
public void test7() {
LongFunction<String> longFunction = x -> (x + "").replace("4", " 8484884 ").trim();
String res = longFunction.apply(484);
// 输出: 8484884 8 8484884
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
ToIntFunction<T>:
int applyAsInt(T value): 入参类型为T,(运行相关逻辑后)返回类型必为int。
使用示例:
/**
* int applyAsInt(T value): 入参类型为T, (运行相关逻辑后)返回类型必为int。
*/
@Test
public void test8() {
ToIntFunction<String> toIntFunction = x -> x == null ? 0 : x.length();
int res = toIntFunction.applyAsInt("蚂蚁呀~嘿!嘿!");
// 输出: 8
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
ToLongFunction<T>:
long applyAsLong(T value): 入参类型为T, (运行相关逻辑后)返回类型必为long。
使用示例:
/**
* long applyAsLong(T value): 入参类型为T, (运行相关逻辑后)返回类型必为long。
*/
@Test
public void test9() {
ToLongFunction<String> toLongFunction = x -> x == null ? 0 : new SecureRandom(x.getBytes()).nextLong();
long res = toLongFunction.applyAsLong("蚂蚁呀~嘿!嘿!");
// 输出: 2677168598702751372
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
ToDoubleFunction<T>:
double applyAsDouble(T value): 入参类型为T,(运行相关逻辑后)返回类型必为double。
使用示例:
/**
* double applyAsDouble(T value): 入参类型为T, (运行相关逻辑后)返回类型必为double。
*/
@Test
public void test10() {
ToDoubleFunction<Float> toDoubleFunction = x -> x == null ? 0.0 : x;
double res = toDoubleFunction.applyAsDouble(123.4F);
// 输出: 123.4000015258789 (注:精度问题不在本文的讨论范围内)
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
IntToDoubleFunction:
double applyAsDouble(int value): 入参类型必须为int,(运行相关逻辑后)返回类型必为double。
使用示例:
/**
* double applyAsDouble(int value): 入参类型必须为int, (运行相关逻辑后)返回类型必为double。
*/
@Test
public void test11() {
IntToDoubleFunction intToDoubleFunction = x -> x + 88.8;
double res = intToDoubleFunction.applyAsDouble(12300);
// 输出: 12388.8
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
IntToLongFunction:
long applyAsLong(int value): 入参类型必须为int,(运行相关逻辑后)返回类型必为long。
使用示例:
/**
* long applyAsLong(int value): 入参类型必须为int, (运行相关逻辑后)返回类型必为long。
*/
@Test
public void test12() {
IntToLongFunction intToLongFunction = x -> x + 1000L;
long res = intToLongFunction.applyAsLong(12345);
// 输出: 13345
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
LongToDoubleFunction:
double applyAsDouble(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为double。
使用示例:
/**
* double applyAsDouble(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为double。
*/
@Test
public void test13() {
LongToDoubleFunction longToDoubleFunction = x -> x + 1000000D;
double res = longToDoubleFunction.applyAsDouble(12345L);
// 输出: 1012345.0
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
LongToIntFunction:
int applyAsInt(long value): 入参类型必须为long,(运行相关逻辑后)返回类型必为int。
使用示例:
/**
* int applyAsInt(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为int。
*/
@Test
public void test14() {
LongToIntFunction longToIntFunction = x -> (int)(x / 1000);
int res = longToIntFunction.applyAsInt(12345L);
// 输出: 12
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
DoubleToIntFunction:
int applyAsInt(double value): 入参类型必须为double,(运行相关逻辑后)返回类型必为int。
使用示例:
/**
* int applyAsInt(double value): 入参类型必须为double, (运行相关逻辑后)返回类型必为int。
*/
@Test
public void test15() {
DoubleToIntFunction doubleToIntFunction = x -> (int)x;
int res = doubleToIntFunction.applyAsInt(123.45);
// 输出: 123
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
DoubleToLongFunction:
long applyAsLong(double value): 入参类型必须为double,(运行相关逻辑后)返回类型必为long。
使用示例:
/**
* long applyAsLong(double value): 入参类型必须为double, (运行相关逻辑后)返回类型必为long。
*/
@Test
public void test16() {
DoubleToLongFunction doubleToLongFunction = x -> (long)x;
long res = doubleToLongFunction.applyAsLong(112233.4455);
// 输出: 112233
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
BiFunction<T, U, R>:
R apply(T t, U u): 输入T类型、U类型的参数,运行相关逻辑后,返回R类型的结果。
使用示例:
/**
* R apply(T t, U u): 输入T类型、U类型的参数,运行相关逻辑后,返回R类型的结果。
*/
@Test
public void test17() {
BiFunction<Integer, String, Staff> biFunction = (x, y) -> {
Staff s = new Staff();
s.setAge(x);
s.setName(y);
return s;
};
Staff staff = biFunction.apply(25, "单身邓");
// 输出: 单身邓, 25岁!
System.out.println(staff.getName() + ", " + staff.getAge() + "岁!");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after): 由一个旧的BiFunction以及一个旧的Function得到一个新的BiFunction<T, U, V>。
假设: 现有式子biFunctionC = biFunctionA.andThen(functionB),biFunctionA泛型为<P1, T1, R1>, functionB泛型为<R1, R2>。
那么, 上述式子的逻辑是:先运行biFunctionA<P1, T1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, T1, R2>的biFunctionC<P1, T1, R2>。
使用示例:
/**
* <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after):
* 由一个旧的BiFunction以及一个旧的Function得到一个新的BiFunction<T, U, V>。
*
* 假设:现有式子biFunctionC = biFunctionA.andThen(functionB),
* biFunctionA泛型为<P1, T1, R1>, functionB泛型为<R1, R2>。
*
* 那么,上述式子的逻辑是:先运行biFunctionA<P1, T1, R1>的apply方法,然后将其返回值
* 作为functionB<R1, R2>的apply方法的入参,执行
* functionB<R1, R2>的apply方法,返回一个泛型为
* <P1, T1, R2>的biFunctionC<P1, T1, R2>。
*/
@Test
public void test18() {
BiFunction<Integer, String, Staff> biFunctionA = (x, y) -> {
Staff s = new Staff();
s.setAge(x);
s.setName(y);
return s;
};
Function<Staff, Map<String, Staff>> functionB = x -> {
Map<String, Staff> map = new HashMap<>(4);
map.put(x.getName(), x);
return map;
};
BiFunction<Integer, String, Map<String, Staff>> biFunctionC = biFunctionA.andThen(functionB);
Map<String, Staff> map = biFunctionC.apply(25, "单身邓");
// 输出: {单身邓=Staff(name=单身邓, age=25, staffNo=null)}
System.out.println(map);
}
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
ToIntBiFunction<T, U>:
int applyAsInt(T t, U u): 入参类型为T和U,(运行相关逻辑后)返回类型必为int。
使用示例:
/**
* int applyAsInt(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为int。
*/
@Test
public void test19() {
ToIntBiFunction<String, Double> toIntBiFunction = (x, y) -> Integer.parseInt(x) + y.intValue();
int res = toIntBiFunction.applyAsInt("123000", 456.789);
// 输出: 123456
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
ToLongBiFunction<T, U>:
long applyAsLong(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为long。
使用示例:
/**
* long applyAsLong(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为long。
*/
@Test
public void test20() {
ToLongBiFunction<String, Double> toLongBiFunction = (x, y) -> Integer.parseInt(x) + y.intValue();
long res = toLongBiFunction.applyAsLong("123000", 456.789);
// 输出: 123456
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
ToDoubleBiFunction<T, U>:
double applyAsDouble(T t, U u): 入参类型为T和U,(运行相关逻辑后)返回类型必为double。
使用示例:
/**
* double applyAsDouble(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为double。
*/
@Test
public void test21() {
ToDoubleBiFunction<String, Double> toDoubleBiFunction = (x, y) -> Integer.parseInt(x) + y;
double res = toDoubleBiFunction.applyAsDouble("123000", 456.789);
// 输出: 123456.789
System.out.println(res);
}
1
2
3
4
5
6
7
8
9
10
^_^ 如有不当之处,欢迎指正
^_^ 参考资料
《jdk api 1.8_google.CHM》
^_^ 测试代码托管链接
https://github.com/JustryDeng…Jdk8Feature
^_^ 本文已经被收录进《程序员成长笔记》 ,笔者JustryDeng
————————————————
版权声明:本文为CSDN博主「justry_deng」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/justry_deng/article/details/100886475