JDK8新特性02:常用函数式接口

Posted 听取虫合声一片

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK8新特性02:常用函数式接口相关的知识,希望对你有一定的参考价值。


,

JDK8新特性02:常用函数式接口

  • 表示函数的接口

    • `Function`接口:单输入单输出函数

      • `Function`接口的意义

      • `Function`的串联: `compose()`,`andThen()`

    • `BiFunction`接口:双输入单输出函数

      • `BiFunction`接口的意义

      • `BiFunction`与`Function`的串联:`andThen()`

    • `BinaryOperator`接口:二元运算符

      • `BinaryOperator`接口的意义

      • 表示取最值的运算符:`minBy()`,`maxBy()`

  • 表示生产者和消费者的接口

    • `Supplier`接口:生产者

    • `Consumer`接口:消费者

  • 表示断言的接口

    • `Predicate`接口:表示断言

      • `Predicate`接口的意义

      • `Predicate`的短路逻辑组合:`and()`,`or()`,`negate()`


表示函数的接口

Function接口:单输入单输出函数

Function接口的意义

阅读Functional接口的文档内容如下:

Represents a function that accepts one argument and produces a result.
This is a functional interface whose functional method is apply(Object)

Function接口表示一个单输入单输出的函数(这一点有点类似于数学上的函数).该接口是一个函数式接口,其所代表的函数行为由apply(Object)方法指定.

下面的例子演示Function接口的使用:

public static int compute(int argument, Function<Integer, Integer> function) {
return function.apply(argument);
}

public static void main(String[] args) {
System.out.println(compute(1, value -> { return value * 2;})); // statement lambda
System.out.println(compute(1, value -> value * 2)); // expression lambda
System.out.println(compute(1, value -> value * value));
}

Function的串联: compose(),andThen()

Function接口中还定义了两个默认方法:compose()andThen(),他们被用于Function的串联.

  1. 阅读compose(Funtion before)方法的文档内容如下:

    Returns a composed function that first applies the before function to its input, and then applies this function to the result.
    If evaluation of either function throws an exception, it is relayed to the caller of the composed function.

    compose(Funtion before)方法返回一个组合函数,该函数先对输入参数应用before对象的apply()方法,再对其应用this对象的apply()方法.若这两个方法中的任一个抛出异常,由调用者处理异常.

  2. 阅读andThen(Funtion after)方法的文档内容如下:

    Returns a composed function that first applies this function to its input, and then applies the after function to the result.
    If evaluation of either function throws an exception, it is relayed to the caller of the composed function.

    andThen(Funtion after)方法返回一个组合函数,该函数先对输入参数应用this对象的apply()方法,再对其应用after对象的apply()方法.若这两个方法中的任一个抛出异常,由调用者处理异常.

下面的例子演示Function串联的使用:

public static int testCompose(int argument, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
return function1.compose(function2).apply(argument);
}

public static int testAndThen(int argument, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
return function1.andThen(function2).apply(argument);
}

public static void main(String[] args) {
System.out.println(testCompose(2, value -> value * 3, value -> value * value)); // 输出12
System.out.println(testAndThen(2, value -> value * 3, value -> value * value)); // 输出36
}

BiFunction接口:双输入单输出函数

BiFunction接口的意义

BiFunction接口与Function接口类似,也代表一个广义上的函数.区别在于该函数为双输入单输出函数.

阅读BiFunctional接口的文档内容如下:

Represents a function that accepts two arguments and produces a result. This is the two-arity specialization of Function.
This is a functional interface whose functional method is apply(Object)

BiFunction接口表示一个双输入单输出的函数,该接口是Function接口的二元特化.该接口是一个函数式接口,其所代表的函数行为由apply(Object)方法指定.

private static int compute(int argument1, int argument2, BiFunction<Integer, Integer, Integer> function) {
return function.apply(argument1, argument2);
}

public static void main(String[] args) {
System.out.println(compute(1, 2, (value1, value2) -> value1 + value2)); // 输出3
}

BiFunctionFunction的串联:andThen()

BiFunction接口的andThen(Function after)方法将BiFunction接口与Function接口进行串联.

阅读andThen(Funtion after)方法的文档内容如下:

Returns a composed function that first applies this function to its input, and then applies the after function to the result.
If evaluation of either function throws an exception, it is relayed to the caller of the composed function.

andThen(Funtion after)方法返回一个组合函数,该函数先对输入参数应用this对象的apply()方法,再对其应用after对象的apply()方法.若这两个方法中的任一个抛出异常,由调用者处理异常.

public static int testAndThen(int argument1, int argument2, BiFunction<Integer, Integer, Integer> function1, Function<Integer, Integer> function2) {
return function1.andThen(function2).apply(argument1, argument2);
}

public static void main(String[] args) {
System.out.println(testAndThen(2, 3, (value1, value2) -> value1 + value2, value -> value * value)); // 输出25
}

BinaryOperator接口:二元运算符

BinaryOperator接口的意义

BinaryOperator接口继承自BiFunction接口,阅读BinaryOperator接口的文档内容如下:

Represents an operation upon two operands of the same type, producing a result of the same type as the operands. This is a specialization BiFunction for the case where the operands and the result are all of the same type.

This is a functional interface whose functional method is apply(Object, Object)

BinayOperator接口表示一个运算,其两个操作数和结果类型均相同.这是BiFunction在输入输出参数类型相同时的特化.该接口是一个函数式接口,其所代表的函数行为由apply(Object)方法指定.

public static int compute(int argument1, int argument2, BinaryOperator<Integer> operator) {
return operator.apply(argument1, argument2);
}

public static void main(String[] args) {
System.out.println(compute(1, 2, (value1, value2) -> value1 + value2)); // 输出3
System.out.println(compute(1, 2, (value1, value2) -> value1 - value2)); // 输出-1
}

表示取最值的运算符:minBy(),maxBy()

BinaryOperator除了继承BiFunction接口的默认方法andThen()之外.还定义了两个静态的的默认方法minBy(),maxBy(),返回一个表示取两参数的最小值和最大值操作的BinaryOperator,接收一个Comparator类型参数,定义排序规则.

  1. 阅读minBy(Comparator comparator)方法的文档内容如下:

    Returns a BinaryOperator which returns the lesser of two elements according to the specified Comparator.

    该方法返回一个BinaryOperator对象,该BinaryOperator对象所定义的逻辑是返回根据指定的Comparator算出的最小值.

  2. 阅读maxBy(Comparator comparator)方法的文档内容如下:

    Returns a BinaryOperator which returns the greater of two elements according to the specified Comparator.

    该方法返回一个BinaryOperator对象,该BinaryOperator对象所定义的逻辑是返回根据指定的Comparator算出的最大值.

public static String getMinString(String str1, String str2, Comparator<String> comparator) {
return BinaryOperator.minBy(comparator).apply(str1, str2);
}

public static void main(String[] args) {
getMinString("hello123", "world", (str1, str2) -> str1.length() - str2.length()); // 输出"world"
getMinString("hello123", "world", (str1, str2) -> str1.charAt(0) - str2.charAt(0)); // 输出"hello123"
}

表示生产者和消费者的接口

Supplier接口:生产者

阅读Supplier接口的文档内容如下:

Represents a supplier of results. There is no requirement that a new or distinct result be returned each time the supplier is invoked.

This is a functional interface whose functional method is get(Object).

Supplier接口表示生产者,不接收输入参数并返回一个输出结果.该接口不要求每次被调用时返回的结果均相同.生产结果的逻辑由get(Object)方法指定.

Supplier接口可以用于工厂.

Supplier<Date> dateSupplier1 = () -> new Date();
System.out.println(dateSupplier1.get());

Supplier<Date> dateSupplier2 = Date::new;
System.out.println(dateSupplier2.get());

Consumer接口:消费者

阅读Consumer接口的文档内容如下:

Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects.

This is a functional interface whose functional method accept(Object).

Consumer接口表示消费者,接收一个输入参数且不返回任何输出结果.不同于其他的函数式接口,Consumer接口是通过函数的副作用执行操作的.消费输入参数的逻辑由accept(Object)方法指定.

表示断言的接口

Predicate接口:表示断言

Predicate接口的意义

阅读Predicate接口的文档内容如下:

Represents a predicate (boolean-valued function) of one argument.

This is a functional interface whose functional method is test(Object).

Predicate接口表示基于单参数的断言,返回一个boolean值.断言的判断逻辑由test(Object)指定.

public static void conditionFilter(List<Integer> list, Predicate<Integer> predicate) {
list.forEach((integer) -> {
if (predicate.test(integer)) {
System.out.println(integer);
}
});
}

public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

conditionFilter(list, item -> item % 2 == 0); // 输出[2, 4, 6, 8, 10]
conditionFilter(list, item -> item > 5); // 输出[6, 7, 8, 9, 10]
conditionFilter(list, item -> true); // 输出整个list
conditionFilter(list, item -> false); // 不输出任何元素
}

Predicate的短路逻辑组合:and(),or(),negate()

Predicate提供了一系列用于进行逻辑组合的默认方法and(Predicate),or(Predicate),negate(),用于对Predicate对象进行逻辑上的与或非操作.注意这里的与和或都带有逻辑短路特性.

public static void conditionFilter(List<Integer> list, Predicate<Integer> predicate1, Predicate<Integer> predicate2) {
list.forEach((integer) -> {
if (predicate1.and(predicate2).negate().test(integer)) {
System.out.println(integer);
}
});
}

public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

conditionFilter(list, item -> item > 5, item -> item % 2 == 0); // 输出[1, 2, 3, 4, 5, 7, 9]
}

,

以上是关于JDK8新特性02:常用函数式接口的主要内容,如果未能解决你的问题,请参考以下文章

Jdk8新特性之4大函数式接口

阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_8_常用的函数式接口_Supplier接口

阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_9_常用的函数式接口_Consumer接口

阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_10_常用的函数式接口_Consumer接口

阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_1_函数式接口的概念&函数式接口的定义

JDK8新特性02 Lambda表达式02_Lambda语法规则