• 1.1 lambda表达式


    一、处理匿名内部类

    1、Runnable接口

    1         new Thread(new Runnable() {
    2             public void run() {
    3                 System.out.println("hello world!!!");
    4             }
    5         }).start();
    6         
    7         // lambda
    8         new Thread(()->System.out.println("hello lambda!!!")).start();

    说明:

    • 上边的方式是原本匿名内部类方式
    • 下边的方法是lambda表达式方式

    lambda基本语法:(形参列表)->{方法体}

    注意:

    • 形参列表:(String x, String y)这样的基本形式
      • 如果没有形参,使用"()",如上
      • 如果参数类型可以被推断出来,使用(x,y)
      • 如果是单个参数且类型可以被推断出来,直接使用x
    • 方法体:如果只有一句话,可以去掉"{}",如上

    2、Comparator接口

     1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya");
     2         //原来的方式
     3         Collections.sort(strList, new Comparator<String>() {
     4             @Override
     5             public int compare(String s1, String s2) {
     6                 return s1.compareTo(s2);
     7             }
     8         });
     9         
    10         //lambda
    11         Collections.sort(strList, (s1, s2)->s1.compareTo(s2));

    说明:这里的s1和s2就被根据comparator的泛型和strList的泛型推断出了类型为String,可以省略参数类型。

    二、方法引用

    1         //lambda
    2         Collections.sort(strList, (s1, s2)->s1.compareTo(s2));
    3         //方法引用
    4         Collections.sort(strList, String::compareTo);
    5         //lambda
    6         strList.forEach(x->System.out.println(x));
    7         //方法引用
    8         strList.forEach(System.out::println);

    说明:

    • 前两个语句效果一样,后两个效果一样,自己比对方法引用与lambda的哪些部分等价
    • 集合类的foreach方法就是增强型for循环的再增强。

    注意:

    • 方法引用的语法
      • 对象::实例方法=>等价于"提供方法参数的lambda表达式"
      • 类::静态方法=>等价于"提供方法参数的lambda表达式"
        • eg. System.out::println等价于x->System.out.println(x)
      • 类::实例方法=>第一个参数是执行方法的对象
        • eg. String::compareTo等价于(s1, s2)->s1.compareTo(s2)

    三、局部变量

    lambda操作的局部变量必须是final型的,即:在lambda表达式所使用到的局部变量(方法体内的变量或形参)只能被读取,不能被改变。

    注意:列出这条约束的原因是防止线程不安全,可能会有疑问,局部变量是方法私有的,怎么会有线程安全问题?

    解释:假设我在该方法体内,启动了一个线程并使用lambda表达式去操作一个局部变量count(注意该变量并没有在lambda中进行声明,但是lambda却可以用,这就是"闭包"),而在该线程外且在该方法体内,该方法也操作了count,这时可能就会有线程安全问题了。

    四、接口的改变

    java的接口也可以写实现default级别的实例方法静态方法了。

     1 public interface LambdaInterface {
     2     //default方法
     3     default void defaultMethod(){
     4         System.out.println("xxxx");
     5     }
     6     //static方法
     7     static void staticMethod(){
     8         System.out.println("xxxx");
     9     }
    10 }
    1 public class TestInterface implements LambdaInterface{
    2     public static void main(String[] args) {
    3         LambdaInterface test = new TestInterface();
    4         test.defaultMethod();//default方法测试
    5         
    6         LambdaInterface.staticMethod();//static方法测试
    7     }
    8 }

    用途:当改造老的项目时,想在旧的接口中添加一些方法,但是又不想让该接口的旧的实现类去实现这些方法时,可以使用这个技巧。

  • 相关阅读:
    npm安装包时的几种模式
    git pull解决冲突
    mysql 连接数据库时时区报错
    idea设置自带的maven为国内镜像
    postgresql 判断字段的长度
    Git删除分支
    win10上安装mysql8(installer方式)并创建用户开启远程连接
    在spring boot中使用jasypt对配置文件中的敏感字符串加密
    spring boot中的底层配置文件application.yam(application.property)的装配原理初探
    CodeForces
  • 原文地址:https://www.cnblogs.com/java-zhao/p/5491078.html
Copyright © 2020-2023  润新知