java lambda表达式及java.util.function下几种常见的接口使用案例

834 阅读5分钟

开始及总结

java.util.function不同类型的接口的区别以及一目了然的作用

  1. Bi开头的接口时双入参
  2. Consumer或者以此结尾的是Void方法没有出参
  3. Predicate或者以此结尾是固定类型(boolean) 返回参数
  4. Supplier表示无入参有返回值
  5. Operator结尾表示入参出参数类型一致

Function的几种情况(就是普通的方法)

  • 写法1 -入参(无),出参(无)
// (没有入参数、没有出参数) 相当于一个没有参数void方法
VoidFunc0 voidFunc0 = () -> System.out.println("入参(无),出参(无)");
VoidFunc0 voidFunc1 = () -> {
    System.out.println("入参(无),出参(无),带{}");
};
// 调用方法 字段方法中的代码
voidFunc0.callWithRuntimeException();
voidFunc1.callWithRuntimeException();
  • 写法2 -入参(有),出参(无)
// 写法2 (有入参数、没有出参数) 相当于一个有参数void方法
VoidFunc<String> voidFunc = (item) -> {
    StringBuilder sb = new StringBuilder();
    String[] items = item;
    for (String value : items) {
        sb.append(value);
        sb.append(",");
    }
    System.out.println("入参(有),出参(无).入参数据:" + sb.substring(0, sb.length() - 1));
};
// 调用方法 字段方法中的代码 任意个数的参数
voidFunc.callWithRuntimeException("参数1", "参数2", "参数3", "参数4");
  • 写法3-(有入参数、有出参数)
// 写法3(有入参数、有出参数) 带{}
Function<String, String> function = (item) -> {
    String res = "[变量]" + item;
    System.out.println("入参(有),出参(有),带{}.入参数据:" + item + ".出参数据:" + res);
    return res;
};
// 执行方法
String result = function.apply("参数1");
// 写法3(有入参数、有出参数) 不带{}
String parameter = "参数1";
Function<String, String> function1 = (item) -> "[变量]" + item;
// 执行方法
String result1 = function1.apply(parameter);
System.out.println("入参(有),出参(有).入参数据:" + parameter + ".出参数据:" + result1);
  • 写法4 -(有入参数(多个)、有出参数)
// 写法4 (有入参数(多个)、有出参数)
BiFunction<String, String, String> biFunction = (item, item1) -> item + item1;
String parameter1 = "参数1";
String parameter2 = "参数2";
String apply = biFunction.apply(parameter1, parameter2);
System.out.println("有入参数(多个)、有出参数.入参数据:" + parameter1 + "," + parameter2 + ".出参数据:" + apply);

对应lambda表达式几种写法

// 入参括号 出参没有
Function<String, Integer> fun1 = (item) -> item.length();
// 入参没有括号 出参没有
Function<String, Integer> fun2 = item -> item.length();
// 入参没有 出参有
Function<String, Integer> fun3 = item -> {
    return item.length();
};
// 入参有 出参有
Function<String, Integer> fun4 = (item) -> {
    return item.length();
};

包下的常用接口使用案例

分类进行举例,列举了每种类型的特点以及实际中的应用场景

  • Finction、BiFunction
    /**
     * 总结: 有入参,返回值
     * Finction 一个入参,有结果
     * BiFunction 双入参,有结果
     */
    @Test
    public void testBiFunction() {
​
        //-------------Finction----------------
        Function<String, String> function = (item) -> item + "da";
        String result = function.apply("大毛");
        System.out.println(result);
​
        //-------------BiFunction----------------
        BiFunction<String, String, Integer> biFinction = (item, item1) -> item.length() + item1.length();
        Integer length = biFinction.apply("6个字符长度", "7个字符长度呀");
        System.out.println("length字符中长度:" + length);
​
        BiFunction<String, String, Integer> biFinction1 = this::biFunctionMethodTest;
        Integer length1 = biFinction1.apply("8个字符长度是吧", "9个字符长度是吧呀");
        System.out.println("length1字符中长度:" + length1);
    }
​
    public Integer biFunctionMethodTest(String item, String item1) {
        return item.length() + item1.length();
    }
​
  • Consumer、BiConsumer
      /**
     * 总结: 有入参,无返回值
     * Consumer 一个入参,无结果
     * BiConsumer 双入参,无结果
     * <p>
     * 这是 BiFunction的专门化,用于操作数和结果都是相同类型的情况
     */
    @Test
    public void testBiConsumer() {
​
        //-------------Consumer----------------
        Consumer<String> consumer = (item) -> {
            System.out.println(item);
        };
        consumer.accept("Consumer:一个入参,无结果");
​
        //-------------BiConsumer----------------
        BiConsumer<String, String> biConsumer1 = (item, item1) -> {
            System.out.println("BiConsumer:双入参,无结果.参数:" + item + "," + item1);
        };
        biConsumer1.accept("参数1", "参数2");
​
        // BiConsumer.andThen  andThen带进入的BiConsumer后执行
        BiConsumer<String, String> biConsumer2 = (item, item1) -> {
            System.out.println("BiConsumer(biConsumer2):双入参,无结果.参数:" + item + "," + item1);
        };
        BiConsumer<String, String> biConsumerAndThen = (item, item1) -> {
            System.out.println("BiConsumerAndThen:双入参,无结果.参数:" + item + "," + item1);
        };
        BiConsumer<String, String> biConsumer3 = biConsumer2.andThen(biConsumerAndThen);
        biConsumer3.accept("参数1", "参数2");
​
        // map forEach 用法 :: 代替 () -> 写法
        BiConsumer<String, String> biConsumer = this::biConsumerMethodTest;
        Map<String, String> contacts = new HashMap<>();
        contacts.put("大毛", "325");
        contacts.put("土豆", "654");
        contacts.put("辰辰", "965");
        // forEach 底层调用 accept 方法
        contacts.forEach(biConsumer);
    }
​
    public void biConsumerMethodTest(String item, String item1) {
        System.out.println("BiConsumer:" + item + item1);
    }
  • Predicate、BiPredicate
   /**
     * 总结: 有入参,返回值固定类型(boolean )
     * Predicate 一个入参,有结果 (结果boolean类型的),通常用于校验或者过滤数据
     * BiPredicate 双入参,有结果 (结果boolean类型的),通常用于校验或者过滤数据
     */
    @Test
    public void testPredicate() {
​
        //-------------Predicate----------------
        Predicate<Integer> predicate = (item) -> item > 2;
        boolean test = predicate.test(1);
        System.out.println(test);
​
        //-------------BiPredicate----------------
        BiPredicate<Integer, Integer> biPredicate = (item, item1) -> item > item1;
        boolean test1 = biPredicate.test(1, 2);
        System.out.println(test1); // 输出false
        // negate 方法获取结果判断结果相反的BiPredicate
        BiPredicate<Integer, Integer> negate = biPredicate.negate();
        boolean test2 = negate.test(1, 2);
        System.out.println(test2);// 输出true
​
        // 使用场景 筛选出结果大于5的数据
        List<Integer> list = Arrays.asList(4, 5, 6, 8, 7, 10, 45, 65, 47);
        List<Integer> filterList = list.stream().filter(item -> item > 5).collect(Collectors.toList());
        System.out.println(filterList);
​
    }
​
  • Supplier
 /**
     * 总结: 无入参,有返回值
     * Supplier 无入参,有结果
     */
    @Test
    public void testSupplier() {
        Supplier<String> supplier = () -> "supplier结果";
        String result = supplier.get();
        System.out.println(result);
        // 使用场景示例: cn.hutool.core.lang.Assert 用法 round值只要不等于5 就抛出异常RuntimeException
        int round = Math.round(50f);
        cn.hutool.core.lang.Assert.isTrue(round == 5, () -> new RuntimeException("运行时异常"));
    }
​
  • UnaryOperator、LongUnaryOperator、IntUnaryOperator
    /**
     * 总结: 一个入参,有返回值  入参返回值类型一致
     * UnaryOperator 一个入参,一个出参类型一致 继承 Function
     * LongUnaryOperator 入参出参类型都是Long
     * IntUnaryOperator  入参出参类型都是Integer
     */
    @Test
    public void testUnaryOperator() {
        //-------------UnaryOperator----------------
        UnaryOperator<String> unaryOperator = item -> "UnaryOperator:" + item;
        String unaryOperatorStr = unaryOperator.apply("大毛呢");
        System.out.println("unaryOperatorStr:" + unaryOperatorStr);
​
        //-------------LongUnaryOperator----------------
        LongUnaryOperator longUnaryOperator = (item) -> item * 2;
        long longUnaryOperatorLog = longUnaryOperator.applyAsLong(256);
        System.out.println("longUnaryOperatorLog:" + longUnaryOperatorLog);
​
        //------------- IntUnaryOperator----------------
        IntUnaryOperator intUnaryOperator = (item) -> item * 3;
        int intUnaryOperatorInt = intUnaryOperator.applyAsInt(256);
        System.out.println("intUnaryOperatorInt:" + intUnaryOperatorInt);
    }
  • ObjLongConsumer、ObjDoubleConsumer、ObjIntConsumer
    /**
     * 总结: 两个入参(第一个参数obj,第二个参数固定的是long),没有回值
     * ObjLongConsumer 两个入参(第一个参数obj,第二个参数固定的是long),没有回值
     * ObjDoubleConsumer、ObjIntConsumer和这个类似的
     */
    @Test
    public void testObjLongConsumer() {
        ObjLongConsumer<String> objLongConsumer = (str, in) -> {
            int res = str.length() + Long.valueOf(in).intValue();
            System.out.println("objLongConsumer:" + res);
        };
        objLongConsumer.accept("dasda", 12);
    }
  • BinaryOperator、DoubleBinaryOperator、LongUnaryOperator
    /**
     * 总结:  双入参,有结果 (入参、出参类型全部一样)
     * BinaryOperator双入参,有结果 (入参、出参类型全部一样)
     * DoubleBinaryOperator 类型是Double
     * LongUnaryOperator 类型是 Long
     * 这是 BiFunction的专门化,用于操作数和结果都是相同类型的情况
     */
    @Test
    public void testBinaryOperator() {
        //-------------BinaryOperator----------------
        BinaryOperator<Integer> binaryOperator = (item, item1) -> item + item1;
        Integer apply = binaryOperator.apply(51, 24);
        System.out.println("BinaryOperator:" + apply);
​
        // BinaryOperator.andThen  andThen带进入的Function后执行
        // andThen 方法参数是  Function(一个入参、一个出参)
        BinaryOperator<Integer> binaryOperator1 = (item, item1) -> item + item1;
        Function<Integer, Integer> function = (item) -> item.intValue() + 30;
        BiFunction<Integer, Integer, Integer> andThenFunction = binaryOperator1.andThen(function);
        Integer apply1 = andThenFunction.apply(12, 12);
        System.out.println("BinaryOperator.andThen:" + apply1); // 输出结果 54 = 12 + 12 + 30
​
        // BinaryOperator 静态方法  取出BinaryOperatorObjTest 对象num小的对象
        BinaryOperatorObjTest binaryOperatorObjTest = new BinaryOperatorObjTest();
        binaryOperatorObjTest.setNum(1);
        BinaryOperatorObjTest binaryOperatorObjTest1 = new BinaryOperatorObjTest();
        binaryOperatorObjTest1.setNum(2);
        BinaryOperator<BinaryOperatorObjTest> tBinaryOperator = BinaryOperator.minBy(Comparator.naturalOrder());
        BinaryOperatorObjTest apply2 = tBinaryOperator.apply(binaryOperatorObjTest, binaryOperatorObjTest1);
        System.out.println("BinaryOperator.minBy" + apply2.toString());
​
        //取2个整数的最小值
        BinaryOperator<Integer> minOperator = BinaryOperator.minBy(Comparator.naturalOrder());
        Integer minInt = minOperator.apply(203, 500);
        System.out.println("BinaryOperator.minBy:" + minInt);
​
        //-------------DoubleBinaryOperator----------------
        DoubleBinaryOperator doubleBinaryOperator = (item1, item2) -> item1 * item2;
        double v = doubleBinaryOperator.applyAsDouble(20, 31);
        System.out.println("DoubleBinaryOperator:" + v);
​
    }
    /**
     * 这里需要涉及到 Comparator 和 Comparable
     */
    public class BinaryOperatorObjTest implements Comparator<BinaryOperatorObjTest>, Comparable<BinaryOperatorObjTest> {
        private String name;
        private Integer num;
​
        @Override
        public String toString() {
            return "BinaryOperatorObjTest{" +
                    "name='" + name + ''' +
                    ", num=" + num +
                    '}';
        }
​
        /**
         * a negative integer, zero, or a positive integer
         * as the first argument is less than,
         * equal to, or greater than the second.
         */
        @Override
        public int compare(BinaryOperatorObjTest o1, BinaryOperatorObjTest o2) {
            int x = o1.getNum().intValue();
            int y = o2.getNum().intValue();
            return (x < y) ? -1 : ((x == y) ? 0 : 1);
        }
​
        public void setName(final String name) {
            this.name = name;
        }
​
        public void setNum(final Integer num) {
            this.num = num;
        }
​
        public String getName() {
            return name;
        }
​
        public Integer getNum() {
            return num;
        }
​
        // 当前值小于 传多来的值就返回-1
        // 相等就返回0
        // 大于就返回 1
        @Override
        public int compareTo(final BinaryOperatorObjTest o) {
            int x = this.getNum().intValue();
            int y = o.getNum().intValue();
            return (x < y) ? -1 : ((x == y) ? 0 : 1);
        }
    }

\