深入浅出理解Java Lambda表达式之四大核心函数式的

编辑: admin 分类: java 发布时间: 2021-12-03 来源:互联网
目录
  • 1.四大核心函数式接口
    • 1.1 Consumer<T> : 消费型接口
    • 1.2 Supplier<T> : 供给型接口
    • 1.3 Function<T, R> : 函数型接口
    • 1.4 Predicate<T> : 断言型接口
  • 2.方法引用
    • 2.1 对象 :: 实例方法
    • 2.2 类 :: 静态方法
    • 2.3 类 :: 实例方法
  • 3.构造器引用
    • 4.数组引用

      1.四大核心函数式接口

      上一篇文章中说到了Lambda表达式中的基本语法,以及我们如何自定义函数式接口。但是在写代码的过程中,大家可能会发现一个问题:当我们有一个新的需求时,可以去自定义一个函数式接口,然后再创建一个它的实现类定义一些相关的业务逻辑行为。那么如果说我们有很多需求、这些需求可能还会不断地变化,那么我们岂不是每次都要去创建新的实现类、同时再去修改之前创建好的实现类中的业务代码?这可太麻烦了吧。。。

      所以呢,Java8就为我们提供了四大核心函数式接口,使用起来非常的方便。

      1.1 Consumer<T> : 消费型接口

      package com.szh.java8;
       
      import org.junit.Test;
       
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.List;
      import java.util.function.Consumer;
      import java.util.function.Function;
      import java.util.function.Predicate;
      import java.util.function.Supplier;
       
      /*
       * 
       */
      public class MyTest3 {
       
          //Consumer<T> : 消费型接口
          @Test
          public void test1() {
              happy(6666.66,(m) -> System.out.println("本地双11共消费 " + m + " 元!!!"));
          }
       
          public void happy(double money, Consumer<Double> consumer) {
              consumer.accept(money);
          }
       
      }

      1.2 Supplier<T> : 供给型接口

      package com.szh.java8;
       
      import org.junit.Test;
       
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.List;
      import java.util.function.Consumer;
      import java.util.function.Function;
      import java.util.function.Predicate;
      import java.util.function.Supplier;
       
      /*
       *
       */
      public class MyTest3 {
       
          //Supplier<T> : 供给型接口
          @Test
          public void test2() {
              List<Integer> numList = getNumList(10, () -> (int)(Math.random() * 100));
              for (Integer num : numList) {
                  System.out.println(num);
              }
          }
       
          public List<Integer> getNumList(int num, Supplier<Integer> supplier) {
              List<Integer> list = new ArrayList<>();
       
              for (int i = 0; i < num; i++) {
                  Integer n = supplier.get();
                  list.add(n);
              }
       
              return list;
          }
       
      }

      1.3 Function<T, R> : 函数型接口

      package com.szh.java8;
       
      import org.junit.Test;
       
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.List;
      import java.util.function.Consumer;
      import java.util.function.Function;
      import java.util.function.Predicate;
      import java.util.function.Supplier;
       
      /*
       * 
       */
      public class MyTest3 {
       
          //Function<T, R> : 函数型接口
          @Test
          public void test3() {
              String trimStr = strHandler("\t\t\t  张起灵-小哥   ", (str) -> str.trim());
              System.out.println(trimStr);
       
              String newStr = strHandler("我喜欢看盗墓笔记呀!!!",(str) -> str.substring(4,8));
              System.out.println(newStr);
          }
       
          public String strHandler(String str, Function<String,String> function) {
              return function.apply(str);
          }
       
      }

      1.4 Predicate<T> : 断言型接口

      package com.szh.java8;
       
      import org.junit.Test;
       
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.List;
      import java.util.function.Consumer;
      import java.util.function.Function;
      import java.util.function.Predicate;
      import java.util.function.Supplier;
       
      /*
       *
       */
      public class MyTest3 {
       
          //Predicate<T> : 断言型接口
          @Test
          public void test4() {
              List<String> list = Arrays.asList("Hello","张起灵-小哥","HashMap","jdk8","List","Set");
              List<String> stringList = filterStr(list, (s) -> s.length() > 5);
       
              for (String string : stringList) {
                  System.out.println(string);
              }
          }
       
          public List<String> filterStr(List<String> strings, Predicate<String> predicate) {
              List<String> strList = new ArrayList<>();
       
              for (String str : strings) {
                  if (predicate.test(str)) {
                      strList.add(str);
                  }
              }
       
              return strList;
          }
      }

      除此之外,还有一些其他的函数式接口,它们有一部分是上面提到的四大核心函数式接口的子接口。

      2.方法引用

      当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用! 方法引用:使用操作符 “ :: ” 将方法名和对象或类的名字分隔开来。

      如下三种主要使用情况 :

      • 对象 :: 实例方法
      • 类 :: 静态方法
      • 类 :: 实例方法

      可以将方法引用理解为 Lambda 表达式的另外一种表现形式,方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致!

      2.1 对象 :: 实例方法

          @Test
          public void test1() {
              Consumer<String> con1 = (str) -> System.out.println(str);
              con1.accept("Hello World!!!");
       
              PrintStream ps = System.out;
              Consumer<String> con2 = ps::println;
              con2.accept("Hello Java8!!!");
       
              Consumer<String> con3 = System.out::println;
              con3.accept("Hello Lambda!!!");
          }

          @Test
          public void test2() {
              Employee emp = new Employee();
              emp.setName("张起灵");
              emp.setAge(18);
       
              Supplier<? extends Object> sup1 = () -> emp.getName();
              String str = (String) sup1.get();
              System.out.println(str);
       
              Supplier<Integer> sup2 = emp::getAge;
              Integer age = sup2.get();
              System.out.println(age);
          }
      package com.szh.java8;
       
      import lombok.AllArgsConstructor;
      import lombok.Data;
      import lombok.NoArgsConstructor;
       
      /**
       *
       */
      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      public class Employee {
       
          private Integer id;
          private String name;
          private Integer age;
          private Double salary;
       
          public Employee(Integer id) {
              this.id = id;
          }
       
          public Employee(Integer id,String name) {
              this.id = id;
              this.name = name;
          }
       
      }

      2.2 类 :: 静态方法

          @Test
          public void test3() {
              Comparator<Integer> com1 = (x,y) -> Integer.compare(x,y);
              System.out.println(com1.compare(10, 20));
       
              Comparator<Integer> com2 = Integer::compare;
              System.out.println(com2.compare(300, 110));
          }

      2.3 类 :: 实例方法

      若 Lambda 的参数列表的第一个参数是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式: ClassName::MethodName

          @Test
          public void test4() {
              BiPredicate<String,String> bp1 = (str1,str2) -> str1.equals(str2);
              System.out.println(bp1.test("Hello", "hello"));
       
              BiPredicate<String,String> bp2 = String::equals;
              System.out.println(bp2.test("Java", "Java"));
          }

      3.构造器引用

      格式 : ClassName::new

      与函数式接口相结合,自动与函数式接口中方法兼容。构造器的参数列表,需要与函数式接口中参数列表保持一致!

      代码中Employee类参考上面的案例。

          @Test
          public void test5() {
              //无参构造器
              Supplier<Employee> sup1 = () -> new Employee();
              System.out.println(sup1.get());
       
              //无参构造器
              Supplier<Employee> sup2 = Employee::new;
              System.out.println(sup2.get());
       
              //一个参数构造器
              Function<Integer,Employee> function = Employee::new;
              Employee employee = function.apply(1001);
              System.out.println(employee);
       
              //两个参数构造器
              BiFunction<Integer,String,Employee> biFunction = Employee::new;
              Employee emp = biFunction.apply(1001, "张起灵");
              System.out.println(emp);
          }

      4.数组引用

      格式 :类型[] :: new

          @Test
          public void test6() {
              Function<Integer,String[]> fun = (x) -> new String[x];
              String[] strings = fun.apply(10);
              System.out.println(strings.length);
       
              Function<Integer,String[]> fun2 = String[]::new;
              String[] strArray = fun2.apply(50);
              System.out.println(strArray.length);
          }

      以上就是深入浅出理解Java Lambda表达式之四大核心函数式的用法与范例的详细内容,更多关于Java Lambda表达式的资料请关注自由互联其它相关文章!

      【文章出处:cc防御 转载请说明出处】