最近 在整RxJAVA 想它用到我们开发的项目中来, 用起来之后发现Rxjava 这种写法真的是很牛B的
特别是配合 新的java8 的lambda 表达式的时候,
ok 下面来学习下 lambda 表达式.
lambda 是java8 的一个新特性, 其实java8 出来也有些时间了, 可是还是不够普及
额 先看看使用起来是什么样子吧:
// 老的用法
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
LogUtil.d("test lambad");
}
};
// lambad表示 用法
Thread thread2 = new Thread(() -> LogUtil.d("test lambad"));
写起来 方便简单多了,
在实现只含有一个抽象方法的接口时,即函数式接口时 就可以使用 lambad 表达式
如上面 的 Runnable 接口, 它只有一个 run方法
就可以 () -> LogUtil.d("test lambda") 代替runnable 了
不仅可以作为参数时 使用, 在写成员变量的时候也可以用:
private Runnable mRunnable = () -> LogUtil.d("");
ok 上面了解了 lambda 的大概使用范围, 以后遇到 只有一个 方法的接口时 都可以考虑使用lambad表达式
ok 下面详细说说 lambda 表达式相关语法:
(parameters) -> expression
(parameters) -> statement
(parameters) -> { statements; }
好像没啥乱用
举例子来说明吧:
省略参数类型
int x, int y) -> { return x + y; };
(x, y) -> { return x + y; };
类型可以省略 , 要么全部省略, 要么都不省略
1个参数时, 可以省略括号
(String text) -> { System.out.println(text); };
(text) -> { System.out.println(text); };
text -> { System.out.println(text); };
上面3种都可以
省略()时 就不能带类型了 String text -> { System.out.println(text); }; // 错误
(int i) -> {
int prod = 1;
for(int n = 0; n < 5; n++) prod *= i;
return prod;
};
函数体只有一行的话可以省略大括号
text -> System.out.println(text);
ssert语句不能省略带括号,比如: s -> { assert !s.isEmpty(); };
return语句不能省略带括号,比如:(x, y) -> return x -y; // 错误
只有一行代码而且有返回值的可以省略return,会返回该行代码计算结果
(x, y) -> { return x -y; };
(x, y) -> x -y;
eturn要和大括号一起省略,比如:(x, y) -> { x - y; }; // 错误
没有参数没有返回值的空函数
() -> {};
用于Lambda时 非final对象 和 非成员变量对象是不可以引用的
如下例子:
Integer i = 100;
i = 111;// 这样 i 是可变的
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
LogUtil.d(TAG, "test " + i);
}
});
Thread thread2 = new Thread(() -> LogUtil.d(TAG, "test lambad" + i));
这样编译器会报错, 错误信息 就合 匿名内部了的一样, 只能引用fainal 对象
Lambda和匿名类区别
public class LambdaTest {
public LambdaTest() {
Function func1 = new Function() {
@Override
public void func() {
System.out.println("Anon Class: " + this.getClass());
}
};
Function func2 = () -> System.out.println("Lambda Exp.: " + this.getClass());
}
}
打印出来的 this 是不一样的
lambda 很少用this
ok 上面就是一些 关于lambda 一下简单内容,
在看lambda的时候还款到 关于java8 接口相关的一些东西
在很多情况下, 接口写好了一般都不能动, 否则 修改一下接口, 那么继承自这个接口的类都需要修改,
但是在java8 中, 对接口做了特殊处理, 使得接口有了更多的扩展性
可以看看如下例子:
public interface IntefaceA {
void fun1(int a);
}
public class ClassA implements IntefaceA {
@Override
public void fun1(int a) {
}
}
后面接口需要做一些修改, 但是又不想修改 ClassA 类
那么就可以使用 接口的默认方法了:
如下:
public interface IntefaceA {
void fun1(int a);
default int fun2(int a, int b) {
return a + b;
}
}
public class ClassA implements IntefaceA {
@Override
public void fun1(int a) {
}
}
public class ClassB implements IntefaceA {
@Override
public int fun2(int a, int b) {
return a + b + b;
}
@Override
public void fun1(int a) {
}
}
这样 ClassA无需做任何修改了, 页实现了接口的修改
继承接口IntefaceA 就必须实现 fun1 方法, 可以选择 是否继承 fun2 方法 如ClassB
然后 接口的引用 可以 调用 fun1 方法 和fun2 方法
这样我们在修改接口的时候, 就不需要修改 以前的一些类了
参考了以下文章