java8 Lambda 表达式 学习

最近 在整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 方法

这样我们在修改接口的时候, 就不需要修改 以前的一些类了


参考了以下文章




















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值