美文网首页
学习RxJava之Lambda表达式

学习RxJava之Lambda表达式

作者: 沙夏cc | 来源:发表于2018-11-19 16:54 被阅读0次

RxJava代码中,除了简洁的链式调用之外,lambda表达式的引入使代码显得更酷了。但是方便的同时带来的问题就是阅读代码的难度提升。因此要求我们对lambda表达式非常的熟悉。这篇文章就讲下lambda表达式的基础知识。

什么是Lambda 表达式

Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包,它是推动 Java 8 发布的最重要新特性。

Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。

使用 Lambda 表达式可以使代码变的更加简洁紧凑。

Lambda表达式的语法

(arg1, arg2...) -> { body }

(type1 arg1, type2 arg2...) -> { body }
// 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)

java8 双冒号的用法

通常看Lambda表达式已经很费劲了,但是有时候Android Studio会提示我们可以把代码更加的化简成

.subscribe(System.out::println);

这种样子,这两个冒号又是什么呢?

这是Java8随Lambda新增的语法符号,叫做方法引用(Method references)
上面这个代码,其实就是

.subscribe(s -> System.out.println(s));

的再化简。具体讲一下:

双冒号(::)操作符是 Java 中的方法引用。 当们使用一个方法的引用时,目标引用放在 :: 之前,目标引用提供的方法名称放在 :: 之后,即 目标引用::方法。比如表达式:

person -> person.getAge();

可以替换成

Person::getAge

表达式

() -> new HashMap<>();

可以替换成

HashMap::new

函数式接口

在 Java 中,函数式接口是只包含一个抽象方法声明的接口。
java.lang.Runnable 就是一种函数式接口,在 Runnable 接口中只声明了一个方法 void run(),相似地,ActionListener 接口也是一种函数式接口,我们使用匿名内部类来实例化函数式接口的对象,有了 Lambda 表达式,这一方式可以得到简化。
类似于

Runnable r = () -> System.out.println("hello world");

当不指明函数式接口时,编译器会自动解释这种转化:

new Thread(
   () -> System.out.println("hello world")
).start();

因此,在上面的代码中,编译器会自动推断:根据线程类的构造函数签名 public Thread(Runnable r) { },将该 Lambda 表达式赋给 Runnable 接口。

以下是一些 Lambda 表达式及其函数式接口:

Consumer<Integer>  c = (int x) -> { System.out.println(x) };

BiConsumer<Integer, String> b = (Integer x, String y) -> System.out.println(x + " : " + y);

Predicate<String> p = (String s) -> { s == null };

写过rxjava的同学看到这里是不是很熟悉这几个函数了?

关于@FunctionalInterface注解

Java 8为函数式接口引入了一个新注解@FunctionalInterface,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。

java8之前已有的函数式接口

java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener

java8新定义的函数式接口

java.util.function中定义了几组类型的函数式接口以及针对基本数据类型的子接口。

Predicate -- 传入一个参数,返回一个bool结果, 方法为boolean test(T t)
Consumer -- 传入一个参数,无返回值,纯消费。 方法为void accept(T t)
Function -- 传入一个参数,返回一个结果,方法为R apply(T t)
Supplier -- 无参数传入,返回一个结果,方法为T get()
UnaryOperator -- 一元操作符, 继承Function,传入参数的类型和返回类型相同。
BinaryOperator -- 二元操作符, 传入的两个参数的类型和返回类型相同, 继承BiFunction

参考资料

相关文章

网友评论

      本文标题:学习RxJava之Lambda表达式

      本文链接:https://www.haomeiwen.com/subject/yyeafqtx.html