Lambda表达式作为Java8的新特性,目的是为了让方法变得更加简洁,不再需要实现接口就可以是执行方法。
表达式只能引用被final修饰的外部变量,同时表达式中的this指向外围实例。
写一个MessageExample接口,实现一个输出语句的例子
public class LambdaExample {
public static void main(String[] args) {
MessageExample messageExample = (s) -> System.out.println();
messageExample.sendMessage("This is a message!");
}
interface MessageExample{
void sendMessage(String s);
}
}
使用lambda对list进行遍历
public class LambdaExample1 {
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
strings.add("This ");
strings.add("is ");
strings.add("a ");
strings.add("message");
strings.add("!");
//老旧的方式,我们不要,毕竟时代在进步
for (String str : strings) {
System.out.print(str);
}
//lambda方式,yes!!!
strings.forEach(s -> System.out.print(s));
//更牛逼的写法,双冒号在java 8被引入成为引用运算法
//可以理解为把lambda表达式的参数直接传入print方法 静态引用
strings.forEach(System.out::print);
}
}
常用的排序功能使用lambda实现
public class LambdaExample2 {
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
strings.add("This ");
strings.add("is ");
strings.add("a ");
strings.add("message");
strings.add("!");
//原生方法
strings.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
//使用lambda对数据进行排序
strings.sort((s1,s2) -> (s1.compareTo(s2)));
//idea的自动提示,为什么这么写我也不知道
strings.sort(String::compareTo);
}
}
package com.yaku.entity;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
我们使用上面的Person类来实现使用lambda进行集合操作的案例
public class LambdaExample3 {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("小强",10));
personList.add(new Person("小明",8));
personList.add(new Person("小红",9));
personList.add(new Person("小花",11));
personList.add(new Person("小明",12));
personList.add(new Person("小黑",15));
//地球被魔法师使用黑魔法袭击,地球上的所有人都长了一岁
personList.forEach(item -> {
item.setAge(item.getAge()+1);
System.out.println(item);
});
Consumer<Person> giveUp = item -> {
item.setAge(item.getAge()+1);
System.out.println(item);
};
//从这里看出写在foreach里面的lambda表达式,实际上被java认为是一个Consumer接口
//而且Consumer是个泛型接口,可以使lambda表达式变得更加灵活
personList.forEach(giveUp);
}
}
从集合中筛选出年龄大于10岁的Person,这里要结合Stream使用
Stream也是Java 8的新特性,这里不过多赘述
public class LambdaExample4 {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("小强",10));
personList.add(new Person("小明",8));
personList.add(new Person("小红",9));
personList.add(new Person("小花",11));
personList.add(new Person("小明",12));
personList.add(new Person("小黑",15));
//可以理解为从stream中过滤,过滤条件为年龄大于10岁
//未来可能趋势打火的链式编程
personList.stream().
filter(item -> item.getAge() > 10).
forEach(System.out::println);
//filter方法中传入的lambda表达式被jvm识别为一个Predicate接口
//所以可以直接用这个接口写lambda表达式然后传入filter方法
Predicate<Person> ageFilter = (p) -> (p.getAge() > 10);
personList.stream().
filter(ageFilter).
forEach(System.out::println);
}
}
通过点进上面两个接口Predicate和Consumer的源码中可以看出,都加上了@FunctionalInterface这个注解,所以说目前我们可以推断出,具有@FunctionalInterface这个注解的接口,都可以看做是一个存储lambda表达式的“{}”。FunctionalInterface中文翻译为功能接口。
我们可以点开Stream的源码看到很多方法。链式编程是如何实现的,原理其实很简单,调用A中的方法,方法执行结束后返回值是A,这个时候我们可以接着调用A中的方法,以此类推我们就实现了链式编程(方法像是被串起来一样执行)。
上面例子我们都是遍历集合并输出,下面这个例子去除集合中大于10岁的Person的姓名
public class LambdaExample5 {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("小强",10));
personList.add(new Person("小明",8));
personList.add(new Person("小红",9));
personList.add(new Person("小花",11));
personList.add(new Person("小明",12));
personList.add(new Person("小黑",15));
//使用Collections的joining方法把符合条件的name拼接成一个字符串
//也可是使用toSet,ToXX方法转换成其他集合
String str = personList.stream().
filter(item -> item.getAge() >10).
map(Person::getName).
collect(Collectors.joining(""));
System.out.println(str);
//把年龄大于10的Person筛选出来
List<Person> collect = personList.stream().
filter(item -> item.getAge() > 10).
collect(Collectors.toList());
System.out.println(collect);
//把personList转化成一个姓名年龄的map
Map<String, Integer> personMap = personList.stream().
collect(Collectors.toMap(item -> item.getName(), item -> item.getAge()));
Map<String, Integer> personMap1 = personList.stream().
collect(Collectors.toMap(Person::getName, Person::getAge));
}
}