【jdk1.8特性】之Function


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值