Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。
这是来自万能的百度百科对于lambda表达式的解释,懂的都懂,不懂的真是听君一席话,如听一席话。
Lambda表达式在Java8中及后续版本占据了举足轻重的地位,对于函数式编程来说是必不可少的一环,所以学会lambda表达式,对于使用Java8的同学是必经之路,举个栗子,Java8中的stream你们不会没有用过吧?什么?你还在用Java7?阿巴阿巴阿巴…好吧,那我直接用代码举个栗子吧。
需求是这样的,二狗第一次来到了大城市,到了大城市就去了大保健,这个时候肯定就要选女朋友了,根据姓名、大小、价位等,咳咳咳…说错了,是根据姓名、鞋码、身价来选择,二哥要求经理让这些女朋友按照身价来正序排队站好。
@Data
@AllArgsConstructor
public class Girl {
private String name;
private Double size;
private Double price;
}
public static void main(String[] args) {
ArrayList<Girl> list = Lists.newArrayList();
list.add(new Girl("露西",33d,2000d));
list.add(new Girl("格蕾丝",36d,3000d));
list.add(new Girl("安娜",28d,1500d));
list.add(new Girl("克瑞斯",31d,1800d));
//匿名函数类实现
list.sort(new Comparator<Girl>() {
@Override
public int compare(Girl o1, Girl o2) {
return o1.getPrice().compareTo(o2.getPrice());
}
});
list.stream().forEach(System.out::println);
Collections.shuffle(list);
System.out.println("-------------我是分隔符-----------------");
//lambda实现
list.sort((Girl g1, Girl g2)-> g1.getPrice().compareTo(g2.getPrice()));
list.stream().forEach(System.out::println);
}
不难看出,两种方式都实现了让女朋友们按照身价排队。那么我们着重来看看Lambda表达式。
(Girl g1, Girl g2)-> g1.getPrice().compareTo(g2.getPrice());
参数列表:本例中是两个Mask对象的参数,采用的是Comparator接口中compare方法的参数。
箭头:->把参数列表和主体分隔为两个部分。
主体:本例中是把比较价格的表达式作为Lambda表达式的返回。主体可以修改成另外一种写法,含义是一样的:
list.sort((Girl g1, Girl g2)-> {
return g1.getPrice().compareTo(g2.getPrice());
});
由此可以看出,lambda表达式语法格式可以分为两种:
1.(parameters) -> expression //参数列表加单条表达式
2.(parameters) ->{ statements; } //参数列表加花括号和多条语句
以下是lambda表达式的重要特征:
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
// 6.接受两个int参数,多条语句进行比较返回1或者0
(int s1, int s2)->{
if(s1>s2){
return 0;
}
return 1;
}
//lambda实现
list.sort((Girl g1, Girl g2)-> g1.getPrice().compareTo(g2.getPrice()));
//lambda简化写法
list.sort((g1, g2)-> g1.getPrice().compareTo(g2.getPrice()));
方法引用通过方法的名字来指向一个方法。方法引用可以使语言的构造更紧凑简洁,减少冗余代码。方法引用使用一对冒号 :: 。
Comparator<Girl> comparator = (g1, g2)-> g1.getPrice().compareTo(g2.getPrice());
//方法引用
Comparator.comparing(Girl::getPrice);
当你需要方法引用时,目标引用放在分隔符::前,方法的名称放在分隔符::后。比如,上面的Girl::getPrice,就是引用了Mask中定义的getPrice方法。方法名称后不需要加括号,因为我们并没有实际调用它。方法引用提高了代码的可读性,也使逻辑更加清晰,在一些stream流中,相信大家也经常会用到。例如
List<String> collect = list.stream().map(Girl::getName).collect(Collectors.toList());
list.stream().forEach(System.out::println);
我们看到第一行通过Girl::getName方法引用,我们收集到了所有女孩的名字,那么第二行我们通过System.out::println打印出了list中的所有对象。
举个栗子,我们先改造一下实体类,增加了空参构造函数,增加了几个方法,有静态方法和非静态方法。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Girl {
private String name;
private Double size;
private Double price;
//Supplier是jdk1.8的接口,这里和lamda一起使用了
public static Girl create(final Supplier<Girl> supplier) {
return supplier.get();
}
public static void makeUp(final Girl girl) {
System.out.println("化妆 " + girl.toString());
}
public void follow(final Girl another) {
System.out.println("Following the " + another.toString());
}
public void dressUp() {
System.out.println("更衣 " + this.toString());
}
}
4种不同的方法引用
//构造器引用:它的语法是Class::new,或者更一般的Class< T >::new实例如下:
Girl girl = Girl.create(Girl::new);
List<Girl> girls = Arrays.asList(girl);
//静态方法引用:它的语法是Class::static_method,实例如下:
girls.forEach(Girl::makeUp);
//特定类的任意对象的方法引用:它的语法是Class::method实例如下:
girls.forEach(Girl::dressUp);
//特定对象的方法引用:它的语法是instance::method实例如下:
girls.forEach(girl::follow);
到这里,大家对lambda表达式应该有了初步的认识,可以在平时编码中多使用,毕竟实战出真知!!
点赞收藏富婆包养