Java8 之 Lambda
2017-08-25 12:47
148 查看
函数接口
函数接口是只有一个抽象方法的的接口,用作 Lambda 表达式类型。例如 View 的 onClickListener 接口就是函数接口
public interface OnClickListener { void onClick(View view); }
使用图形可以清晰表达函数接口
为 Button 设置监听事件
mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Log.d(TAG, "Hello Lambda"); } });
匿名内部类的设计是为了方便程序员,但是也造成了代码的冗余和可读性差的问题。
Lambda 表达式
把上面代码用 Lambda 表达式转化如下mButton.setOnClickListener(view -> Log.d(TAG, "Hello Lambda"));
Lambda 表达式为
view -> Log.d(TAG, "Hello Lambda"),这个意思就很明确了,用参数 view 来输出一条 Log 信息,所以 Lambda 表达式简洁地表达了一种行为。
view 为 Lambda 表达式参数,Log.d() 为 Lambda 表达式的主体。 同时需要注意,如果主体只有一行代码,不需要在后面加上分号。
Lambda 表达式类型推断
Java 是静态语言, 然而上面的例子中的 Lambda 表达式中的参数 view 并没有声明类型,这是由 javac 根据上下文推断出来的,就如同 Java7 中的类型推断HashMap<String, String> map = new HashMap<>();
Lambda 表达式返回值
函数接口 Predicate 如下public interface Predicate<T> { boolean test(T var1); }
用这个接口来进行一个过滤操作
List<Integer> list = Stream .of(1, 2, 3) .filter(new Predicate<Integer>() { @Override public boolean test(Integer integer) { return 1 > 2; } }) .collect(Collectors.toList());
然后转化为 Lambda 表达式
List<Integer> list = Stream .of(1, 2, 3) .filter(integer -> 1 > 2) .collect(Collectors.toList());
注意到 test() 方法的返回值 boolean,然而在 Lambda 表达式的主体中并没有明确用 return 来返回,也就是说,Lambda 表达式自动取了主体的(1 > 2) 的结果。
再来看一个例子
mButton.setOnClickListener(view -> view.getId());
这个是不是也很奇怪,onClickListener 接口中的 onClick() 方法的返回是 void,而 Lambda 表达式主体的返回是 int,而这个时候 Lambda 表达式根据 onClick() 返回值,并不会自动获取 view.getId() 的返回值。
Lambda 表达式形式
无参 Lambda 表达式
new Thread(() -> Log.d(TAG, "run")).start();
代码很简单,创建一个线程并运行。 这里的 Lambda 表达式是无参的,用一对括号表示无参。
有参 Lambda 表达式
前面例子中演示了一个参数的 Lambda 表达,再看看多参的情况Stream.of(1, 2, 3).reduce(new BinaryOperator<Integer>() { @Override public Integer apply(Integer integer1, Integer integer2) { return integer1 + integer2; } });
BinaryOperator 也是一个函数接口,apply() 方法有两个参数,转化为 Lambda 表达式如下
Stream.of(1, 2, 3).reduce((integer1, integer2) -> integer1 + integer2);
Lambda 表达式主体
Lambda 表达式主体不仅仅是一个表达式,还可以是一个代码块mButton.setOnClickListener(view -> { view.getId(); Log.d(TAG, "hello Lambda"); });
Lambda 表达式主体如果是代码块,每一个表达式后面都要带分号;
方法引用
Lambda 有一个常见的用法就是经常调用参数,例如mButton.setOnClickListener(view -> view.getId());
由于这种 Lambda 用法比较普遍,所以 Java 8 为其提供一个简洁地语法,叫做方法引用。所以上面的 Lambda 表达式可以转化如下
mButton.setOnClickListener(View::getId);
方法引用的标准语法为 ClassName::methodName。
方法引用中,调用的方法后面没有跟上一对括号
相关文章推荐
- Java8之lambda最佳实践_动力节点Java学院整理
- java8——使用lambda和枚举实现简洁、可读性良好的策略模式
- Java8初体验(一)lambda表达式语法
- Java8 利用Lambda处理List集合
- Java8新特性 -- Lambda 方法引用和构造器引用
- Java8特性详解 lambda表达式 Stream
- Java 8中的 Lambda表达式
- Java 8 Lambda 捕获外部变量 -- 不可变的原因
- Java Lambda表达式入门
- JAVA8 Lambda(1)
- 深入浅出 Java 8 Lambda 表达式
- java8-Lambda中比较器Comparator的使用
- lambda -- Java8
- java8学习之Lambda表达式深入与流初步
- java lambda 表达式中的双冒号的用法 ::
- java8 Lambda表达式
- java8 lambda表达式 (1)
- Java8 学习笔记--函数式接口与lambda表达式的关系
- java lambda学习
- JAVA Lambda Expressions streams