2017-10-24
1 Lambda表达式是什么
2 Lambda表达式语法
3 函数式接口是什么
3.1 常用函数式接口
4 Lambdas和Streams结合使用
4.1 使用forEach方法
4.2 使用过滤器filter方法
4.3 使用limit方法
4.4 使用sorted方法
4.5 使用map方法
4.6 使用parallelStream方法
4.7 使用summaryStatistics方法
参考
1 Lambda表达式是什么
Lambda 表达式是一种匿名函数(对 Java 而言这并不完全正确。在Java中,Lambda 表达式是对象,他们必须依附于一类特别的对象类型——函数式接口(functional interface))。Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式就和方法一样,它提供了一个正常的参数列表(argument)和一个使用这些参数的主体(body)。
Lambda 表达式为 Java 添加了缺失的函数式编程特点,使我们能将函数当做一等公民看待。
Lambda表达式还增强了集合库。 Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及java.util.stream 包。 流(stream)就如同迭代器(iterator),但附加了许多额外的功能。 总的来说,lambda表达式和 stream 是自Java语言添加泛型(Generics)和注解(annotation)以来最大的变化。
2 Lambda表达式语法
Java 中的 Lambda 表达式通常使用 (argument) -> {body} 语法书写,例如:
(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }
以下是一些 Lambda 表达式的例子:
(int a, int b) -> { return a + b; } () -> System.out.println("Hello World"); (String s) -> { System.out.println(s); } () -> 42 () -> { return 3.1415 };
Lambda表达式结构说明:
- 一个 Lambda 表达式可以有零个或多个参数
- 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同
- 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
- 空圆括号代表参数集为空。例如:() -> 42
- 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
- Lambda 表达式的主体可包含零条或多条语句
- 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
- 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空
3 函数式接口是什么
函数式接口是只包含一个抽象方法声明的接口。
java.lang.Runnable 就是一种函数式接口,在 Runnable 接口中只声明了一个方法 void run(),相似地,ActionListener 接口也是一种函数式接口,我们使用匿名内部类来实例化函数式接口的对象,有了 Lambda 表达式,这一方式可以得到简化。Runnable接口代码如下:
@FunctionalInterface public interface Runnable { public abstract void run(); }
每个 Lambda 表达式都能隐式地赋值给函数式接口。如下代码:
Runnable r = () -> System.out.println("hello world");
Runnable的Lambda表达式和匿名内部类的使用示例
public void sample01() { // 1.1使用匿名内部类 new Thread(new Runnable() { @Override public void run() { System.out.println("1.1 Hello world !"); } }).start(); // 1.2使用 lambda expression new Thread(() -> System.out.println("1.2 Hello world !")).start(); // 2.1使用匿名内部类 Runnable race1 = new Runnable() { @Override public void run() { System.out.println("1.3 Hello world !"); } }; // 2.2使用 lambda expression Runnable race2 = () -> System.out.println("1.4 Hello world !"); // 直接调用 run 方法(没开新线程哦!) race1.run(); race2.run(); }