基本概念
jdk8中新增了lambda表达式,lambda是一个希腊字母,长得像汉字“入”。先看一个例子:
String[] planets = new String[]{"Mercury", "Venus", "Earth", "Mars",
"Jupiter", "Saturn", "Uranus", "Neptune"};
Arrays.sort(planets, (first, second) -> first.length() - second.length());
sort方法应该传入一个Comparator实例,而此处却传入了一个代码块,翻译成匿名内部类方式:
Arrays.sort(planets, new Comparator<String>() {
@Override
public int compare(String first, String second) {
return first.length() - second.length();
}
});
显然,lambda表达式简洁的多。
(first, second)表示参数列表,大家可能有一个疑问,java是个强类型语言,这里却没有写明参数类型,这是因为编译器会推导出参数类型,当然你也可以这样写:
Arrays.sort(planets, (String first, String second) -> first.length() - second.length());
这样也没有任何问题。
如果无参数可以用 "()"表示。
"->"箭头后表示一个表达式,如果需要更长的表达式可以用大括号括起来:
() -> { for(int i = 0; i < 100; i ++) System.out.println(i); }
函数式接口
对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口称为函数式接口(functional interface)
比如Runnable接口,只有一个run()方法,适用于lambda表达式。
jdk8在java.util.function包下新增了大概二三十个函数式接口,这边列举几个常用的几个:
函数式接口 | 参数类型 | 返回类型 | 抽象方法名 | 描述 | 其它方法 |
---|---|---|---|---|---|
Predicate<T> | 无 | boolean | test | 布尔值函数 | and,or,negate,isEqual |
Supplier<T> | 无 | T | get | 提供一个T类型的值 | |
Consumer<T> | T | void | accept | 处理一个T类型的值 | andThen |
Function<T,R> | T,U | void | apply | 处理T和U | compose,andThen,identity |
UnaryOperator<T> | T | void | apply | 类型T上的一元操作符 | compose,andThen,identity |
BinaryOperator<T> | T,T | void | apply | 类型T上的二元操作符 | andThen,maxBy,minBy |
package java8.lambda.functional;
import java.util.Comparator;
import java.util.function.*;
/**
* Description:
* <p>
* Created by nathan.z on 2018/9/2.
*/
public class FunctionalTest {
public static void consume(int n, Consumer<Integer> consumer) {
for (int i = 0; i < n; i ++) {
consumer.accept(i);
}
}
public static void consumeAndThen(int n, Consumer<Integer> before, Consumer<Integer> after) {
for (int i = 0; i < n; i ++) {
before.andThen(after).accept(i);
}
}
public static void supply(Supplier<String> supplier) {
System.out.println("supply a string: " + supplier.get());
}
public static void predicate(Predicate<Integer> predicate, int value) {
if (predicate.test(value)) {
System.out.println("test result is true");
}
}
public static void functionCompose(Function<Integer, Integer> a, Function<Integer, Integer> b, Integer x) {
System.out.println(a.compose(b).apply(x));
}
public static void binaryOperatorMinBy(BinaryOperator<Integer> operator, Comparator<Integer> c, Integer a, Integer b) {
System.out.println(BinaryOperator.minBy(c).apply(a, b));
}
public static void main(String[] args) {
printLine("测试consumer.andThen");
consumeAndThen(1, i -> System.out.println(i), i -> System.out.println("after"));
printLine("测试supplier");
supply(() -> "supplier test");
printLine("测试predicate");
predicate(x -> x > 0, 5);
printLine("测试function.compose");
functionCompose(x -> x * x, x -> 2 * x, 10);
printLine("测试BinaryOperator.minBy");
binaryOperatorMinBy((x , y) -> x + y, (x ,y) -> x - y, 10, 20);
}
public static void printLine(String str) {
System.out.println();
System.out.println("============ " + str + " ============");
}
}
结果:
============ 测试consumer.andThen ============
0
after
============ 测试supplier ============
supply a string: supplier test
============ 测试predicate ============
test result is true
============ 测试function.compose ============
400
============ 测试BinaryOperator.minBy ============
10
以上是lambda的基本用法。