美文网首页
Java - lambda我也能学会

Java - lambda我也能学会

作者: kikiki1 | 来源:发表于2019-07-08 10:12 被阅读0次

    我们首先看一个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::getProperty
    System.out::println
    "abc"::length
    ArrayList::new
    int[]::new
    

    相关文章

      网友评论

          本文标题:Java - lambda我也能学会

          本文链接:https://www.haomeiwen.com/subject/zobnhctx.html