zoukankan      html  css  js  c++  java
  • lambda表达式

    (o1,o2)->Integer.compare(o1,o2);
    //example 1:  不用lambda表达式
          Comparator<Integer> comparator = new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return Integer.compare(o1,o2);
                }
          };
          System.out.println(comparator.compare(71, 22));  // result:1
    //example 2:  用lambda表达式
            Comparator<Integer> comparator1 = (o1, o2) -> Integer.compare(o1,o2);
            System.out.println(comparator1.compare(22, 22));  // result:0
    //example 3:  用方法引用
            Comparator<Integer> comparator2 = Integer ::compare;
            System.out.println(comparator2.compare(11, 44));  // result:0
    
    • 格式:
      ->左边:lambda的形参列表(接口中抽象方法的形参列表)
      ->右边:lambda体(重写的抽象方法的方法体)
      lambda本质:接口的实例
    • lambda使用:
      ->左边:lambda的形参中参数类型可以省略,其中只有一个参数,可以省区小括号()
      ->右边:lambda体 用{}包裹,若:lambda只有一条执行语句,则{}可以省略,若是return 语句,则省略{}时,必须省略return关键字。
    //1. 无参
          Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println("ddd");
                }
            };
            runnable.run();  //调用run()方法
    
            Runnable runnable1 = () -> System.out.println("ddd"); //lambda
            runnable1.run();    
    //2. 有一个参数,没有返回值
          Consumer<String> consumer = new Consumer<String>() {
                @Override
                public void accept(String s) {
                    System.out.println("consumer--" + s);
                }
            };
            consumer.accept("abc");  //result:consumer--abc
            //Consumer<String> consumer1 = (String s) -> {
            Consumer<String> consumer1 = (s) -> {  //省去String,叫做类型推断
                System.out.println("consumer--" + s);
            };
            consumer1.accept("123");  //result: consumer--abc
            //当lambda体只有一句语句时 {} 可以省略
            Consumer<String> consumer2 = (s) -> System.out.println("consumer--" + s);;  
            consumer2.accept("456");  //result: consumer--456
    
    // 3. 参数类型只有一个,()可以省略
          Consumer<String> consumer1 = s -> {  //省去()
                System.out.println("consumer--" + s);
            };
            consumer1.accept("123");  //result: consumer--abc
    // 4. 只有一条执行语句,则{}可以省略,若是`return `语句,则省略{}时,必须省略`return`关键字。
          Comparator<Integer> comparator3 = new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1 + o2;
                }
            };
            System.out.println(comparator3.compare(1, 2)); //result: 3
    
            Comparator<Integer> comparator4 = (o1,o2) -> o1 + o2;
            System.out.println(comparator4.compare(1, 3)); ////result: 4
    
    • 对于只有一个抽象方法的接口, 需要这种接口的对象时, 就可以提供一个 lambda 表达式。 这种接口称为函数式接口 (functional interface )
      函数式接口:
    //1. Consumer<T>
    @FunctionalInterface
    public interface Consumer<T> {
          void accept(T t);
          default Consumer<T> andThen(Consumer<? super T> after){
                //see resource code
          }
    }
    //2. Supplier<T>
    @FunctionalInterface
    public interface Supplier<T> {
    
        T get();
    }
    // 3. Function<T, R>
    @FunctionalInterface
    public interface Function<T, R> {
    
        R apply(T t);
        ...
    }
    // 4. Predicate<T>
    @FunctionalInterface
    public interface Predicate<T> {
    
        boolean test(T t);
        default Predicate<T> and(Predicate<? super T> other) {}
        default Predicate<T> negate(){}
        default Predicate<T> or(Predicate<? super T> other){}
        static <T> Predicate<T> isEqual(Object targetRef){}
    }
    
    • 方法引用:
    object::instanceMethod
    Class::staticMethod
    Class::instanceMethod 
    

    在前 2 种情况中, 方法引用等价于提供方法参数的 lambda 表达式。 如:System.out::println 等价于 x-> System.out.println(x)。 类似地,Math::pow 等价于(x,y)-> Math.pow(x, y)。
    对于第 3 种情况, 第 1 个参数会成为方法的目标。例如,String::compareToIgnoreCase
    同于 (x, y)-> x.compareToIgnoreCase(y)

    /**
      ① Consumer中的 void accept(T t);
      ② PrintStream中的 println(T t); 
     要求:①中的参数列表和②中参数列表一样,①中的返回值和②中的返回值一样
    */
    //1. object::instanceMethod
          Consumer<String> consumer = new Consumer<String>() {
                @Override
                public void accept(String s) {
                    System.out.println(s);
                }
            };
            consumer.accept("abc");  //result: abc
    
            PrintStream ps = System.out;
            Consumer<String> consumer1 = ps::println; 
            consumer1.accept("ddd");  //result: ddd
    /**
    Comparator中的int compare(T t1, T t2);
    Integer中的 int compare(T t1, T t2) 参数列表和返回值一样
    */
    // 2. Class::staticMethod
          Comparator<Integer> comparator = new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return Integer.compare(o1,o2);
                }
            };
            System.out.println(comparator.compare(22, 22));  //result: 0
    
            Comparator<Integer> comparator1 = Integer::compare;  
            System.out.println(comparator1.compare(23, 32));   //result: -1
    /**
    Comparator中的int compare(T t1, T t2);
    String 中的 int compareTo(T t);        
    */
    // 3. Class::instanceMethod
            Comparator<String> comparator = (o1, o2) -> o1.compareTo(o2);
            System.out.println(comparator.compare("df", "fd"));  //result: -2
    
            Comparator<String> comparator1 = String::compareTo;
            System.out.println(comparator1.compare("df", "df")); //result: 0
    
    • 构造器引用:和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致,抽象方法的返回值类型即为构造器所属的类的类型。如:Person :: new ,它是Person构造器的一个引用。
    • 数组引用:将数组看成一个类即可。就和构造器一样了。如:int[] :: new,相当于lambda表达式的 length -> new int[Length]
    • 变量作用域:
    public static void repeat(String text, int count){
          for (int i = 1; i <= count; i++){
                ActionListener listener = event ->{
                      System.out.pn'nt1n(i + ": " + text);
                      // Error: Cannot refer to changing i
                      };
                new Timer(1000, listener).start();
                }
          }
    }
    

    这里有一条规则:lambda 表达式中捕获的变量必须实际上是最终变量 ( effectivelyfinal)。实际上的最终变量是指, 这个变量初始化之后就不会再为它赋新值。在这里,text 总是指示同一个 String 对象,所以捕获这个变量是合法的。不过,i 的值会改变,因此不能捕获 i。

  • 相关阅读:
    python D32 管道、线程池
    python D31 守护进程、进程锁、队列
    python D30 进程
    python 30 进程之间的相互独立、进程之间的时间差
    python D30 操作系统历史
    python D29 socketserver以及FTB
    python D28 粘包
    net4.0 task 超时任务代码 用Thread.sleep方式实现
    sql取随机结果集
    【ecshop---新增包邮卡功能】
  • 原文地址:https://www.cnblogs.com/huyuqing/p/14270808.html
Copyright © 2011-2022 走看看