java8-lambda表达式

来源:互联网 发布:淘宝内衣模特拍摄 编辑:程序博客网 时间:2024/05/21 12:40

什么是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(),还有方法引用,也是非常优秀的新特性

原创粉丝点击