【jdk1.8特性】之Function

笔者日常 来吧,Function~


相关声明

  • 本文按照以下顺序进行说明并给出简单的使用示例:

    序号接口
    1Function<T, R>
    2IntFunction<R>
    3DoubleFunction<R>
    4LongFunction<R>
    5ToIntFunction<T>
    6ToLongFunction<T>
    7ToDoubleFunction<T>
    8IntToDoubleFunction
    9IntToLongFunction
    10LongToDoubleFunction
    11LongToIntFunction
    12DoubleToIntFunction
    13DoubleToLongFunction
    14BiFunction<T, U, R>
    15ToIntBiFunction<T, U>
    16ToLongBiFunction<T, U>
    17ToDoubleBiFunction<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;
    
    }
    

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());
    }
    
  • 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);
     }
    
  • 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);
     }
    
  • 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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    

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() + "岁!");
     }
    
  • 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);
     }
    

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);
     }
    

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);
     }
    

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);
     }
    


^_^ 如有不当之处,欢迎指正

^_^ 参考资料
        《jdk api 1.8_google.CHM》

^_^ 测试代码托管链接
         https://github.com/JustryDeng…Jdk8Feature

^_^ 本文已经被收录进《程序员成长笔记》 ,笔者JustryDeng

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值