Lambda 表达式
Lambda 表达式
举例
(o1, o2) -> Integer.compare(o1, o2);
格式
1. ->
: lambda 操作符 或 箭头操作符
2. 左边: lambda 行参列表 = 抽象方法的行参列表
3. 右边 lambda 体 = 抽象方法的方法体
lambda 表达式的本质
作为函数式接口的实例
快速入门
利用 Runnable 接口 使用 Lambda 表达式
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("hello word");
}
};
r1.run();
Runnable r2 = () -> System.out.println("hello word");
r2.run();
利用 Comparator 接口 使用方法引用
Comparator<Integer> c1 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
System.out.println(c1.compare(1, 2));
Comparator<Integer> c2 = Integer::compare;
System.out.println(c2.compare(1, 2));
使用
无参无返回值
Runnable r2 = () -> System.out.println("hello word");
r2.run();
需要一个参数无返回值
Consumer<String> c1 = (s) -> System.out.println(s);
Consumer<String> c2 = System.out::println;
c1.accept("1");
c1.accept("2");
两个或以上参数,多条执行语句有返回值
Comparator<Integer> com1 = (a, b) -> {
System.out.println(a);
System.out.println(b);
return a.compareTo(b);
};
System.out.println(com1.compare(1, 2));
函数式接口
如果一个接口中只声明了一个抽象方法,则此接口就称为函数式接口可用
@FunctionalInterface
注解,可用通过 lambda 表达式使用函数式接口
函数式接口
@FunctionalInterface
public interface MyInterface {
void method1();
}
java 内置四大核心的函数式接口
| 函数式接口 | 参数 | 返回 | 用途 |
| -------------------- | ---- | ------- | ------------------------------------------------------------ |
| Consumer\<T> 消费型 | T | void | 对类型为T对象应用操作包含方法: void accept(T t)
|
| Supplier\<T> 供给型 | 无 | T | 返回类型为T对象,包含方法 T get()
|
| Function<T,R> 函数型 | T | R | 对象类型为T对象应用操作并返回返回结果<br />结果是R类型的对象包含方法 R apply (T t)
; |
| Predicate\<T> 断定型 | T | boolean | 启动类型为T的对象是否满足某约束,并返回Boolean值<br />包含方法 boolean test(T t)
|
扩展的函数接口
| 函数式接口 | 参数 | 返回 | 用途 |
| ------------------ | ---- | ---- | ---- |
| BiFunction<T,U,R> | T,U | R | 对类型为 T,U 参数应用操作,返回 R 类型的结果包含方法为 R apply(T t, U u)
; |
| UnaryOperator\<T> | T | T | 对类型为T的对象进行一元运算, 并返回T类型的结果包含方法为: T apply(T t)
; |
| BinaryOperator\<T> | T,T | T | 对类型为 T 的对象进行二元运算,并返回T类型的结果。包含方法为 T apply(T t1, T t2)
|
| BiConsumer<T, U> | T, U | void | 对类型为 T,U 参数进行应用操作。包含方法为 void accept(T t, U u)
|
| BiPredicate<T,U> | T,U | boolean | 包含方法为 boolean test(T t, U u)
; |
| ToIntFunction\<T><br />LongFunction\<T><br />ToDoubleFunction\<T> | T | int<br />long<br />double | 分别计算 int、long、double 值的函数 |
| IntFunction\<R><br />LongFunction\<R><br />DoubleFunction\<R> | int<br />long <br />double | R | 参数分别为 int、long、double类型的函数 |
部分使用
Consumer 使用
public static <T> void print(T s, Consumer<T> consumer) {
consumer.accept(s);
}
@Test
public void test3() {
// hello
Demo2.print("hello", a ->
System.out.println(a.length() >= 5 ? a : "字数不足"));
}
Sepplier 使用
public int calcSum (Supplier<int[]> supplier) {
final int[] ints = supplier.get();
return Arrays.stream(ints).sum();
}
@Test
public void test4() {
// 6
calcSum(() -> new int[]{1, 2, 3});
}
Function 使用
public String [] handlerString(String[] s, Function<String, String> handler) {
return Arrays.stream(s).map(handler).toArray(String[]::new);
}
@Test
public void test5() {
String [] a = new String[]{"1", "2", "3"};
// a1, a2, a3
Arrays.toString(handlerString(a, s -> "a" + s));
}
Predicate 使用
public String isPrint(String surname, String name, Predicate<String> predicate) {
if (predicate.test(name)) {
return surname + name;
} else {
return surname;
}
}
@Test
public void test6() {
// xiaou
isPrint("xiaou", "", name -> !name.isEmpty());
// xiaou66
isPrint("xiaou", "66", name -> !name.isEmpty());
}
方法引用
当要传递给 lambda 体的操作,已经有实现的方法就可用使用方法引用
对象 :: 非静态方法
在 Supplier 中 get 方法 T get();
在 Users 中 getName 方法 String getName()
因为函数的方法参数一致返回值一致
@Test
public void test7 () {
Users user = new Users("xiaou");
Supplier<String> getName = user::getName;
// xiaou
getName.get();
}
类 :: 静态方法
Comparator 方法 int compare(T o1, T o2)
Integer compare 方法 int compare(int x, int y)
因为函数的方法参数一致返回值一致
@Test
public void test8() {
Comparator<Integer> s = Integer::compare;
// -1
s.compare(1,2);
}
类 :: 非静态方法
第一种情况
在 Users 中 getName 方法 String getName()
在 Function 函数方法 R apply(T t);
@Test
public void test9() {
// Users :: getName = 传递进来的 Users 对象调用 getName
// 也就是将第一个参数作为调用对象
Function<Users, String> getName = Users::getName;
getName.apply(new Users("xiaou"));
}
第二种情况
Comparator 方法 int compare(T o1, T o2)
String compareTo 方法 int compareTo(String anotherString)
@Test
public void test10() {
// 将第一个参数作为调用对象 "1".compareTo("2")
Comparator<String> s = String::compareTo;
// -1
s.compare("1", "2");
}
实际应用
在枚举类中使用
enum OrderTransform {
ORDER_SN("订单号", "$.orderSn", null),
AFTER_SALES_STATUS("订单状态", "$.afterSalesStatus", (csvRow) -> {
String status = csvRow.getByName(OrderTransform.AFTER_SALES_STATUS);
return status;
}),
;
private String title;
private String jsonPath;
private Function<CsvRow, String> getValue;
}