JDK8常用函数式接口:`Consumer` / `Function`

Consumer<T> 函数式接口

Consumer 函数式接口适用于,只需要接收一个参数且不需要返回值的情况下,可使用Consumer接口进行实现。

示例:

  public static void output(Consumer<String> consumer){

    String text = "桃李不言下自成蹊";

    consumer.accept(text);

  }
  @Test
  void testConsumer() {

    output(s -> System.out.println("向控制台输出:"+s));
    
    output(s -> {
      System.out.println("向XXX网站发送数据包:"+s);
    });
  }
向控制台输出:桃李不言下自成蹊
向XXX网站发送数据包:桃李不言下自成蹊

请看是不是完成了我们即向控制台打印,又向网站发送数据包的工作。consumer接口是用于只需要接收一个参数,且不需要任何返回的情况下,我们可以对consumer进行实现,同时很里边尤其只有唯一的方法,except代表我们业务的处理过程,当时行except的时候,他就会去调用

-> System.out.println("向控制台输出:"+s)
//or
 -> {
      System.out.println("向XXX网站发送数据包:"+s);
    }

这里的代码。

Consumer接口的优势是什么?

Consumer接口主要是对入参,做一系列的业务操作,如判断业务,没有返回值。

例如找出名称为"lili"的人员,如下:

Function<T,R>函数式接口

Function 函数式接口适用于,在有一个输入参数且需要有返回值的情况下,可使用Function接口进行实现。

示例:以生成定长随机字符串为例

  private String chars = "abcdefghijklmnopqrstuvwxyz0123456789";

  private Function<Integer, String> randomStringFunction =
      length -> {
        StringBuilder stringBuffer = new StringBuilder();

        Random random = new Random();

        for (int i = 0; i < length; i++) {
          // 0-字符串长度随机长度
          int position = random.nextInt(chars.length());

          stringBuffer.append(chars.charAt(position));
        }
        return stringBuffer.toString();
      };

  @Test
  void randomStringFunction() {
    String randomString = randomStringFunction.apply(32);

    System.out.println(randomString);
    //out: wyrx3o6bzz4bj0h7b4u3awed8abdkqzj
  }

示例2:使用Function函数式接口,完成寻找List集合中最大值的功能,

运行效果如下

  private Function<List<Integer>, Integer> maxNum = list1 -> {
    Integer max = 0;
    for (Integer integer : list1) {
      if (integer  > max) {
        max = integer;
      }
    }
    return max;
  };

  @Test
  void testMax() {

    List<Integer> asList = Arrays.asList(1, 12, 24, 2, 24, 18, 101);
    Integer max = maxNum.apply(asList);
    System.out.println("max = " + max);
  }

总结

常用的是这三个consumer代表对应一个输入参数无输出的功能代码,而function对应一个输入参数且需要返回数据的功能代码,而这个predicate则用于条件判断,固定返回布尔值用来对输入的数据进行或者判断。这个时候我们又会衍生出来一个新的问题,你会发现无论是这三个接口,他都要求只有一个输入参数的情况下,那么如果有多个输入参数时怎么办呢?

很遗憾在我们Java中默认提供的这些函数式接口,它最多只支持一个参数,如果要多参数的情况下,我们就需要自己来编写函数式接口了。只要你的一个接口符合,尤其只有一个抽象方法的条件的话,我们就可以称这个接口是函数式接口。对于我们来说函数式接口它也提供了一个特别的注解@FunctionalInterface,用来说明咱们来看一下,呼叫代码在前面课程中在讲解number表达时。

@FunctionalInterface
public interface MathOperation {
    float operator(int a, int b);
}

class ILambdaTest {
    @Test
    void testLambdaOperator() {
        // 标准写法
        MathOperation add =  (a, b) -> {
            System.out.println("加法运算");
            return a + b;
        };
        // 简洁写法
        MathOperation subtruction = (a, b) -> a - b;

        System.out.println("add = " + add.operator(1,3));
        System.out.println("subtruction = " + subtruction.operator(1,3));
    }
}