jdk1.8 新特性之 lambda表达式

来源:互联网 发布:药品数据查询 编辑:程序博客网 时间:2024/06/05 15:49

我们首先看一个java实现多线程的lambda表达式的例子

常规

Runnable runnable = new Runnable(){            @Override            public void run() {                System.out.println("多线程");            }};

lambda形式

Runnable runnable = () -> {            System.out.println("多线程");        };

简洁
此方法使用的场景只能是实现的方法中只有一行语句。

Runnable runnable = () -> System.out.println("多线程");

Lambda在Collections中的用法

public class StreamExample {    public static void main(String[] args) {        List<Integer> myList = new ArrayList<>();        for(int i=0; i<100; i++) myList.add(i);        //有序流        Stream<Integer> sequentialStream = myList.stream();        //并行流        Stream<Integer> parallelStream = myList.parallelStream();        //使用lambda表达式,过滤大于90的数字        Stream<Integer> highNums = parallelStream.filter(p -> p > 90);        //lambdag表达式 forEach循环        highNums.forEach(p -> System.out.println("最大数 并行="+p));        Stream<Integer> highNumsSeq = sequentialStream.filter(p -> p > 90);        highNumsSeq.forEach(p -> System.out.println("最大数 有序="+p));    }}

输出结果

最大数 并行=91最大数 并行=96最大数 并行=93最大数 并行=98最大数 并行=94最大数 并行=95最大数 并行=97最大数 并行=92最大数 并行=99最大数 有序=91最大数 有序=92最大数 有序=93最大数 有序=94最大数 有序=95最大数 有序=96最大数 有序=97最大数 有序=98最大数 有序=99

为什么要使用Lambda表达式

1.简化代码行数
2.顺序执行或并行执行
以下为例子之间的对照

//传统形式private static boolean isPrime(int number) {            if(number < 2) return false;    for(int i=2; i<number; i++){        if(number % i == 0) return false;    }    return true;}
//使用表达式的private static boolean isPrime(int number) {            return number > 1            && IntStream.range(2, number).noneMatch(                    index -> number % index == 0);}

为了更好的可读性,我们还可以这么写

private static boolean isPrime(int number) {    IntPredicate isDivisible = index -> number % index == 0;    return number > 1            && IntStream.range(2, number).noneMatch(                    isDivisible);}

我们来看一个计算数字集合总合的例子,它有一个参数将用来传递表达式后处理得到最终的结果。

public static int sumWithCondition(List<Integer> numbers, Predicate<Integer> predicate) {        return numbers.parallelStream()                .filter(predicate)                .mapToInt(i -> i)                .sum();    }

比如我们将传递这样的如下条件

//统计所有数字总合sumWithCondition(numbers, n -> true)//统计所有偶数总合sumWithCondition(numbers, i -> i%2==0)//统计所有大于5的总合sumWithCondition(numbers, i -> i>5)

接下来我再来看一个更加偷懒的Lambda表达式

//找出3-11之间最大的奇数,并求它的平方private static int findSquareOfMaxOdd(List<Integer> numbers) {        int max = 0;        for (int i : numbers) {            if (i % 2 != 0 && i > 3 && i < 11 && i > max) {                max = i;            }        }        return max * max;    }

我们使用Lambada重写它

class NumberTest{    public static int findSquareOfMaxOdd(List<Integer> numbers) {            return numbers.stream()                    .filter(NumberTest::isOdd)                    .filter(NumberTest::isGreaterThan3)                    .filter(NumberTest::isLessThan11)                    .max(Comparator.naturalOrder())                    .map(i -> i * i)                    .get();        }        public static boolean isOdd(int i) {            return i % 2 != 0;        }        public static boolean isGreaterThan3(int i){            return i > 3;        }        public static boolean isLessThan11(int i){            return i < 11;        }}

Lambada表达式例子

() -> {}                     // 没有参数,没有返回值() -> 42                     // 没有参数,方法体有表达式() -> null                   // 没有参数,方法体有表达式() -> { return 42; }         // 没有参数,方法体有返回值() -> { System.gc(); }       // 没有参数,有方法体// 有多种返回值() -> {  if (true) return 10;  else {    int result = 15;    for (int i = 1; i < 10; i++)      result *= i;    return result;  }}                          (int x) -> x+1             // 单个参数(int x) -> { return x+1; } // 单个参数,跟上面一样(x) -> x+1                 // 单个参数,跟下面一样x -> x+1                   (String s) -> s.length()   (Thread t) -> { t.start(); } s -> s.length()              t -> { t.start(); }          (int x, int y) -> x+y      // 多个参数,有返回值(x,y) -> x+y               // 跟上面一样(x, final y) -> x+y        // 多个参数,有不能修改的参数(x, int y) -> x+y          // 这个是非法的,不能混合写

方法跟构造函数可以用下面这种方式

System::getPropertySystem.out::println"abc"::lengthArrayList::newint[]::new
1 0