可以把Lambda表达式理解为 简洁的可传递的匿名函数 的一种方式
它没有名称,但有参数列表、函数主题、返回类型、可抛出的异常列表
表达式
分为三部分:参数列表、箭头、Lambda主体
( parameters ) -> expression
( parameters ) -> { statements; }
例子
//1. 布尔表达式(参数为Apple,返回Boolean)
(Apple a) -> a.getWeight() > 150
//2. 组合两个值(参数为2个int,返回为int)
(int x, int y) -> x*y
//3. 创建对象(无参,返回一个对象)
() -> new Apple(10)
//4. 从一个对象中选择/抽取(参数为String,返回int)
(String s) -> s.length()
//5. 比较两个对象(参数为2个Apple,返回为int)
(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())
//6. 消费一个对象(参数为Apple,无返回值)
(Apple a) -> {
System.out.println("苹果的重量为:");
System.out.println(a.getWeight());
}
函数式接口就是只定义一个抽象方法的接口
例如:
public interface Comparator<T>{
int compare(T o1, T o2);
}
public interface Runnable{
void run();
}
Lambda与函数式接口的关系
Lambda表达式允许以内联的形式为函数式接口的抽象方法提供实现
Lambda把整个表达式作为函数式接口的实例
例子
// Lambda实现
Runnable r1 = () -> System.out.println(" Lambda:Hello World! ");
// 匿名类实现
Runnable r2 = new Runnable(){
public void run(){
System.out.println(" Anonymous:Hello World! ");
}
}
// 普通调用
public static void process(Runnable r){
r.run();
}
process(r1);
process(r2);
// Lambda调用
process(() -> System.out.println(" Lambda:Hello World! "));
常用函数式接口
Predicate 接口 (断言:一个参数,返回boolean)
Predicate predicate = (s) -> s.length() > 0;
predicate.test("foo"); // true
predicate.negate().test("foo"); // false
Predicate nonNull = Objects::nonNull;
Predicate isNull = Objects::isNull;
Predicate isEmpty = String::isEmpty;
Predicate isNotEmpty = isEmpty.negate();
Consumer 接口 (消费者:执行在单个参数上的操作)
Consumer greeter = (p) -> System.out.println("Hello, " + p.firstName);
greeter.accept(new Person("Luke", "Skywalker"));
Supplier 接口 (提供者:无参数,返回一个结果)
Supplier personSupplier = Person::new;
personSupplier.get(); // new Person
Function 接口 (方法:一个参数,返回一个结果)
Function<String, Integer> toInteger = Integer::valueOf;
Function<String, String> backToString = toInteger.andThen(String::valueOf);
String result = backToString.apply("123"); // "123"
参考:https://www.cnblogs.com/heimianshusheng/p/5672641.html
方法引用可以重复使用现有的方法定义,并像Lambda一样传递
Lambda | 方法引用 |
---|---|
(Apple a) -> a.getWeight() | Apple::getWeight |
() -> Thread.currentThread().dumpStack() | Thread.currentThread::dumpStack |
(str,i) -> str.substring(i) | String::substring |
(String s) -> System.out.println(s) | System.out::println |
1.引用静态方法
//lambda表达式
Arrays.sort(persons, (o1, o2) -> Person.compareByAge(o1,o2));
//引用类的静态方法
Arrays.sort(persons, Person::compareByAge);
2.引用某个对象的实例方法
ComparisonProvider provider = new ComparisonProvider();
//lambda表达式
Arrays.sort(persons,(a,b)->provider.compareByAge(a,b));
//引用的是对象的实例方法
Arrays.sort(persons, provider::compareByAge);
3.引用某个类型的任意对象的实例方法
String[] stringsArray = {"Hello","World"};
//lambda表达式
Arrays.sort(stringsArray,(s1,s2) -> s1.compareToIgnoreCase(s2));
//引用类型对象的实例方法
Arrays.sort(stringsArray, String::compareToIgnoreCase);
4.引用构造方法
final List personList = Arrays.asList(persons);
//lambda表达式
Set personSet = transferElements(personList,()-> new HashSet<>());
//引用构造方法
Set personSet2 = transferElements(personList, HashSet::new);
参考博客:https://www.cnblogs.com/JohnTsai/p/5806194.html
Lambda表达式可以理解为是一种可以简洁传递代码的匿名函数
另外,只有接受函数式接口的地方才可以使用Lambda表达式
通过方法引用可以让我们的代码更加简洁