java8-lambda表达式

什么是Lambda表达式

这里首先要提到一个概念:函数式接口

  • Java中只有一个抽象方法的接口,用来表示lambda表达式的类型,JAVA8中新增了许多函数式接口。比如断言接口Predicate,表示函数的Function等。

简单的说,如果你接触过C++,C#之类的编程语言,也许会听说过函数式编程、函数引用之类的概念,他们与lambda表达式功能类似,通俗的说就是,现在你可以更简单的在JAVA中把方法当做一个参数传递给另一个方法,或者可以不用再写那么复杂的匿名内部类(可读性差,稍复杂)去实现一些必要的接口。


有这样一个例子我觉得很好,

现在有一个List<Integer> numbers,我们要达到三种结果,获得所有integer的和,获得集合中所有偶数的和,获得所有奇数的和。
  • 没有lambda时,你可能最先想到的就是写三个如下方法
public int sumAllSth (List<Integer> numbers){
    int total = 0;
    for(int n:numbers){
        if(//这个数是奇数或偶数){
            total += number;
        }
    }
    return total;
}
但是当你需要再次加入一个获取所有质数的和时,你就要找到这个类,再次添加方法了。这样明显有大量的代码冗余,也不利于维护。
  • 当然你也可以使用设计模式——策略模式来完成这个任务
public int sumAllSth (List<Integer> numbers){
    int total = 0;
    for(int n:numbers){
        if(strategy.test(number)){//返回true或false
            total += number;
        }
    }
    return total;
}
多余的代码不写了… 策略模式可以在影响主程序段环境(Context)的情况下,通过多个实现了抽象策略(Strategy)的抽象策略类(ConcreteStrategy),是的这些策略可以被替换。但是代码量也变大了。
  • Lambda表示式
public int sumAll(List<Integer> numbers, Predicate<Integer> p) {  
    int total = 0;  
    for (int number : numbers) {  
        if (p.test(number)) {  
            total += number;  
        }  
    }  
    return total;  
}  

//part 1: 
        System.out.println( sumAll(numbers, n -> n % 2 == 0) );  

//part 2:
        System.out.println( sumAll(numbers, new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                return integer%2==0;
            }
        }));
对于part1部分,就是我们的lambda表达式,暂时忽略那些横线箭头,表达式能达到的作用就是part2部分。
正如part2,当你准备使用类似Predicate的函数式接口,有一个test方法用来断言,返回是true或者false,当需要灵活变动if()中的条件时,Predecate可以经过test()多次传递达到可变条件的效果。也就是要实现一个匿名内部类时,6行代码里的核心其实只有return integer%2=0这一段,而lambda表达式在这里就简练很多,并且性能也会提升。

  • Lambda表达式语法:
(params) -> expression
(params) -> statement
(params) -> { statements }
  • 主要包括

    • 圆括号中的参数
    • ->
    • 花括号中的表达式
  • 基本规则

    • 参数与表达式可为0,也可有多个多行
    • 当参数/表达式为1时,可以省略圆括号/花括号
    • 参数类型可以指定,可以省略(省略时编译器会根据上下文去判断)
    • 当表达式只有一条时,返回值就是表达式的返回值

再介绍一个使用场景:下面是JAVA8中对于迭代器interface Iterator新增的的函数式接口:
default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
下面就出现了比起for(:)更加简便的写法,说起来,其实他们都是java的语法糖:
        List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7);

        //lambda
        numbers.forEach( value -> System.out.print(value) );

        //方法引用
        numbers.forEach(System.out::print);
对于foreach()的好基友stream(),还有方法引用,也是非常优秀的新特性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值