• Java8之Lambda表达式基础


      Java 8中,将会提供对lambda的支持,函数式编程FP(Functional Programming)将会得到很好地支持,而函数式编程的一个重要特点就是适合并行运算。

      

      λ:希腊字母表中排序第十一位的字母,英语名称为Lambda,读音:兰亩达。

      语法如下:

      (parameters) -> expression
      (parameters) -> statement
      (parameters) -> {statements;}

      例子如下:

      () -> Math.PI * 2.0
      (int i) -> i * 2
      (String s) -> s.length()
      (int i0, int i1) -> i0 + i1
      (int x, int y) -> { return x + y; }

      更多的特性:

      一、省略参数类型

      (int x, int y) -> { return x + y; };
      可以省略参数类型,写成(x, y) -> { return x + y; };

      不能只省略一部分类型,比如:(int x, y) -> { return x + y; };    //error

      二、1个参数可以省略括号

      (String text) -> { System.out.println(text); };
      可以写为:(text) -> { System.out.println(text); };
           也可以写为: text -> { System.out.println(text); };

      但是不能带类型,比如:String text -> { System.out.println(text); };   //error

      三、函数体多行时需要大括号

      (int i) -> {
           int prod = 1;
           for(int n = 0; n < 5; n++) prod *= i;
              return prod;
      };

      四、函数体只有一行时有些情况下可以省略大括号

      text -> System.out.println(text);

      注:assert语句不能省略带括号,比如: s -> { assert !s.isEmpty(); };

      注:return语句不能省略带括号,比如:(x, y) -> return x -y;   //error

      五、只有一行代码而且有返回值的可以省略return,会返回该行代码计算结果

      (x, y) -> { return x -y; };
      (x, y) -> x -y;

      注:return要和大括号一起省略,比如:(x, y) -> { x - y; };    //error

      

      六、用于Lambda的变量不可变

    int portNumber = 1337;
    Runnable r = () -> System.out.println(portNumber); // OK
    
    // 编译错误
    // Local variable portNumber defined in an enclosing scope must be final or effectively final
    int portNumber = 1337;
    Runnable r = () -> System.out.println(portNumber); // NG
    portNumber = 1338;
    
    // 通过数组实现
    final int[] wrappedNumber = new int[] { 1337 };
    Runnable r = () -> System.out.println(wrappedNumber[0]); // OK
    wrappedNumber[0] = 1338;

      Lambda可以传递给任何希望是函数式接口的地方,比如遍历List:

      Arrays.asList("a", "b", "c").forEach(x -> System.out.println(x));

      也可以接住异常堆栈信息看看Lambda是怎么执行的:

    String[] datas = new String[]{""};
    Arrays.asList(datas).stream().forEach(name -> check(name));
    
    public static int check(String s) {
        if (s.equals("")) {
            throw new IllegalArgumentException();
        }
        return s.length();
    }

      

      Java 8 的类库包含一个新的包 java.util.functions ,这个包中有很多新的功能接口,这些接口可与集合类一起使用。 

    List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Dave"); 
    
    List<String> filteredNames = names 
            .filter(e -> e.length() >= 4) 
            .into(new ArrayList<String>()); 
    
    for (String name : filteredNames) {  
        System.out.println(name); 
    } 

      上述的例子还可以写为:

    List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Dave");   
    names   
       .filter(e -> e.length() >= 4)   
       .forEach(e -> { System.out.println(e); });  

      一段代码这样写:

    // 求一个List中的最大值    
    public static void main(String[] args) {  
            List<Integer> k = new ArrayList<Integer>();  
            k.add(1);  
            k.add(2);  
            k.add(3);  
            k.add(8);  
            k.add(11);  
            k.add(20);  
            k.add(50);  
            int max = Integer.MIN_VALUE;  
            for (int j : k) {  
                if (max < j) {  
                    max = j;  
                }  
            }  
            System.out.println(max);  
    }  

      

      假如这段代码中查找最大值成了性能瓶颈,那么需要将这段代码改为并发操作。想想就不容易。那现在使用lamda表达式这样写:

    // 求一个链表中的最大值   
    public static void main(String[] args) {  
              
            List<Integer> k = new ArrayList<Integer>();  
            k.add(1);  
            k.add(2);  
            k.add(3);  
            k.add(8);  
            k.add(11);  
            k.add(20);  
            k.add(50);  
            Optional<Integer> max = k.stream().max((a,b) -> {return a-b;});  
            System.out.println(max);  
    }  

      想变成并发操作这样写:

    // 求一个链表中的最大值   
    public static void main(String[] args) {  
              
            List<Integer> k = new ArrayList<Integer>();  
            k.add(1);  
            k.add(2);  
            k.add(3);  
            k.add(8);  
            k.add(11);  
            k.add(20);  
            k.add(50);  
            Optional<Integer> max = k.parallelStream().max((a,b) -> {return a-b;});  
            System.out.println(max);  
    }  

      很简单吧。就是将k.stream() 改成 k.parallelStream()

      详细的可以参考:http://blog.csdn.net/cctt_1/article/details/24835803

      

  • 相关阅读:
    解析库的使用---页面解析总结
    django--学习笔记 一
    项目(三)--个人博客开发
    算法图解(python3版本)--读后感
    "mysql技术内幕innodb存储引擎"--读书笔记
    通过ftp同步服务器文件:遍历文件夹所有文件(含子文件夹、进度条);简单http同步服务器文件实例
    使用node-webkit(v0.35.5)和innosetup(3.6.1)打包将web程序打包为桌面客户端(安装包)
    .netcore3.1使用ELK日志中心(使用NLog数据传输)
    .netcore3.1使用skywalking8.1.0(docker-compose一键部署)
    asp.net 页面刷新锚点失效问题解决
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/4340204.html
Copyright © 2020-2023  润新知