Java8新特性–Lambda表达式
Lambda表达式的本质就是一个匿名函数,利用Lambda表达式可以把函数作为参数传递进方法中。之所以将其命名为Lambda,是因为其原理涉及Lambda演算。
基础语法
lambda 表达式的语法格式如下:
() -> /* 表达式 */ expression
() -> { /* 语句 */ statements; }
parameter -> expression
parameter -> { statements; }
(parameters) -> expression
(parameters) ->{ statements; }
以下是lambda表达式的重要特征:
- **可选类型声明:**不需要声明参数类型,编译器可以统一识别参数值。
- **可选的参数圆括号:**一个参数无需定义圆括号,但多个参数需要定义圆括号,用逗号隔开。
- **可选的大括号:**如果主体包含了一个语句,就不需要使用大括号,甚至不需要return关键字。
- **可选的返回关键字:**如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
实例
/**
* 排序
*/
List<Integer> list = Arrays.asList(5, 4, 3, 2, 1, 6);
/**
* public static <T> void sort(List<T> list, Comparator <? super T> c) {
* list.sort(c);
* }
*/
Collections.sort(
list,
(x, y) -> {
// 内部迭代
System.out.println(x + ":" + y + "=" + x.compareTo(y));
return x.compareTo(y);
// 倒序
// return -Integer.compare(x, y);
}
);
函数式接口
函数式接口,接口中只有一个抽象方法的接口,并使用@FunctionalInterface修饰。
package cn.charliejohn.service;
@FunctionalInterface
public interface StrTool {
public String getValue(String str);
}
@FunctionalInterface
public interface StrToolPlus<T, R> {
public R getValue(T tOne, T tTwo);
}
四大核心函数式接口
函数式接口 | 参数类型 | 返回类型 | 用 途 |
---|---|---|---|
Consumer消费型接口 | T | void | 对类型为T的对象应用操作,包含方法void accept(T t) |
Supplier供给型接口 | 无 | T | 返回类型为T的对象,包含无参方法T get(); |
Function<T, R>函数型接口 | T | R | 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法R apply(T t) |
Predicate断定型接口 | T | boolean | 确定类型为T的对象是否满足某约束,并返回Boolean值,包含方法Boolean test(T t) |
实例
// Consumer
Consumer<String> consumer = System.out::println;
consumer.accept("hello");
// Supplier
Supplier<String> stringSupplier = String::new;
String suppliertr = stringSupplier.get();
System.out.println(suppliertr.getClass());
// Function
Function<String, String> stringFunction = String::new;
String str = stringFunction.apply("hello");
System.out.println(str);
// Predicate
public static void main(String[] args) {
System.out.println(filterStr("hi", s -> s.length() > 3));
}
public static String filterStr(String string, Predicate<String> predicate) {
return predicate.test(string) ? string : "pass";
}
方法引用与构造器引用
方法引用
若Lambda体中的内容有方法已经实现,可以使用方法引用。
语法格式
obj::method
ClassName::static
ClassName::method
注意:
- 第一个参数是实例方法的调用者,第二个是实例方法的参数可以用
ClassName::method
!
实例
/**
* obj::method
*/
Consumer<String> consumer = System.out::println;
consumer.accept("hello");
/**
* ClassName::static
*/
Comparator<Integer> comparator = Integer::compare;
/**
* ClassName::method
* 返回Boolean
*/
BiPredicate<String, String> biPredicate = String::equals;
构造器引用
ClassName::new
实例
/**
* ClassName::method
*/
Function<String, String> stringFunction = String::new;
String str = stringFunction.apply("hello");
System.out.println(str);