Lambda表达式是java8的新特性,没用过的人可能会对它比较抵触,用过的人呢又为之痴迷。在Lambda表达式中,有个很重要的用法是简化某些匿名类,我们通过下面的例子来感受一下。
有个老婆婆有一只鸡每天都要生蛋,她每天都要给鸡蛋记上生产日期
无参无返回值
1.7及之前的写法如下:
定义一个标记鸡蛋的接口MarkEgg:
public interface MarkEgg {
void mark();
}
然后用匿名类调用,记录10天老婆婆的动作。
public class OldLady {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
mark(new MarkEgg() {
@Override
public void mark() {
System.out.println("今天的鸡蛋");
}
});
}
}
public static void mark(MarkEgg markEgg) {
markEgg.mark();
}
}
我们可以看到,虽然匿名类省略了类名,但是还是不够简洁的。我们看看用Lambda是怎么简化代码的。
public class OldLady {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
mark(() -> System.out.println("今天的鸡蛋"));
}
}
public static void mark(MarkEgg markEgg) {
markEgg.mark();
}
}
另外,在MarkEgg接口上,要标记@FunctionalInterface
,这个注解表示,这个接口是函数式接口,如果我们标记了@FunctionalInterface
,但它却不是函数式接口,编译器就会报错,但是不写也是可以的,如同@Override
。
@FunctionalInterface
public interface MarkEgg {
void mark();
}
下面对比一下两个主体部分:
Lambda表达式有三个部分:
第一个是参数列表,对应图中的1
,这里例子没有参数。
第二个是->
,把参数和Lambda主体分开。
第三个是Lambda主体,对应上面的输出语句2
。
无参有返回值
老婆婆并不会写字,所以她让别人代写,只需要跟别人说在鸡蛋写什么
MarkEgg接口简单的改一下:
@FunctionalInterface
public interface MarkEgg {
String mark();
}
OldLady类:
public class OldLady {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
mark(() -> "今天的鸡蛋");
}
}
public static void mark(MarkEgg markEgg) {
System.out.println(markEgg.mark());
}
}
注意一下,Lambda主体中,并没有return。
有参有返回值
此时,别人跟老婆婆说,你每次都写今天,你以后怎么知道是哪天的,所以你要告诉我是哪天。
MarkEgg接口加上参数:
@FunctionalInterface
public interface MarkEgg {
String mark(int day);
}
OldLady类:
public class OldLady {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
mark((int day) -> String.format("第%s天的鸡蛋", day), i + 1);
}
for (int i = 0; i < 10; i++) {
mark(day -> String.format("第%s天的鸡蛋", day), i + 1);
}
}
public static void mark(MarkEgg markEgg, int day) {
System.out.println(markEgg.mark(day));
}
}
我们上面参数,有两个形式,第一个是(int day)
,第二个直接是day
,把参数类型去掉。
总结
Lambda的基本语法是
(parameters) -> expression
或(我们上面都是单行的,如果是多行,就要加大括号,且如果是有返回值要加return
)
(parameters) -> { statements; }
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。