Java8 -- 03 -- lambda表达式

原文链接:Java8 – 03 – lambda表达式


相关文章:


Java8 中的一个重要特性就是支持了 lambda 表达式,所谓 lambda 表达式可以简单地理解为传递匿名函数的一种方式,它没有名称,但有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表,有以下几点特点:

  • 匿名

    • lambda 表达式不想普通方法那样拥有一个明确的名称
  • 函数

    • lambda 表达式不想普通方法那样属于某个特定的类,但和方法相同的是,lambda 表达式也有参数列表、函数主体、返回类型,以及可能还有一个可以抛出的异常列表
  • 传递

    • lambda 表达式可以作为参数传递给方法或存储在变量中
  • 简洁

    • lambda 表达式无需像匿名内部类一样写很多模板代码

一、使用局部变量


  • Apple.java

    public class Apple {
    
        private String color;
        private Integer weight;
    
        public Apple(String color, Integer weight) {
            this.color = color;
            this.weight = weight;
        }
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    
        public Integer getWeight() {
            return weight;
        }
    
        public void setWeight(Integer weight) {
            this.weight = weight;
        }
    
        @Override
        public String toString() {
            return "Apple{" +
                    "color='" + color + '\'' +
                    ", weight=" + weight +
                    '}';
        }
    }
    

二、方法引用

  • 方法引用可以让我们重复使用现有的方法定义,根据已有的方法来创建 lambda 表达式

  • 当我们使用方法引用时,目标引用放在分隔符 :: 前面,方法名称放在 :: 后面,如:Apple::getWeight 就是引用了 Apple 类中定义的方法 getWeight (不需要括号),是 lambda 表达式 (Apple apple) -> apple.getWeight() 的快捷写法

    List<String> list = Arrays.asList("C", "a", "d", "B");
    list.sort(String::compareTo); // [B, C, a, d]
    System.out.println(list);
    
    list.sort(String::compareToIgnoreCase);
    System.out.println(list); // [a, B, C, d]
    
  • 方法引用主要有三类

    • 指向静态方法的方法引用

      Integer::parseInt
      
    • 指向任意类型实例方法的方法引用

      String::length
      
    • 指向现有对象的实例方法的方法引用

      Apple apple = new Apple();
      Consumer<String> consumer = apple::setColor;
      

三、构造函数引用

  • 对于一个现有的构造函数,我们可以利用它的名称和关键字 new 来创建一个它的引用,如:ClassName::new,它的功能与指向静态方法的引用类似

    • 无参构造

      Supplier<Apple> supplier = Apple::new;
      Apple apple = supplier.get();
      
      // 等价于
      
      Supplier<Apple> supplier = () -> new Apple();
      Apple apple = supplier.get();
      
    • 有参构造(构造函数签名为:Apple(String color))

      Function<String, Apple> function = Apple::new;
      Apple apple = function.apply("red");
      
      // 等价于
      
      Function<String, Apple> function = str -> new Apple();
      Apple apple = function.apply("red");
      
    • 有参构造(构造函数签名为:Apple(String color, Integer weight))

      BiFunction<String, Integer, Apple> biFunction = Apple::new;
      Apple apple = biFunction.apply("red", 15);
      
      // 等价于
      
      BiFunction<String, Integer, Apple> biFunction = (color, weight) -> new Apple(color, weight);
      Apple apple = biFunction.apply("red", 15);
      

四、使用 lambda 表达式

  • 比较器复合

    List<Apple> inventory = new ArrayList<>(Arrays.asList(
            new Apple("red", 15),
            new Apple("green", 10),
            new Apple("blue", 25),
            new Apple("black", 20)));
    
    // 正序
    inventory.sort(Comparator.comparing(Apple::getWeight));
    // [Apple{color='red', weight=10}, Apple{color='red', weight=15}, 
    // Apple{color='black', weight=20}, Apple{color='blue', weight=25}]
    System.out.println(inventory);
    
    // 倒序
    inventory.sort(Comparator.comparing(Apple::getWeight).reversed());
    // [Apple{color='blue', weight=25}, Apple{color='black', weight=20}, 
    // Apple{color='red', weight=15}, Apple{color='red', weight=10}]
    System.out.println(inventory);
    
  • 谓词复合

    • 过滤方法

      public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate predicate) {
          List<Apple> result = new ArrayList<>();
          inventory.forEach(apple -> {
              if (predicate.test(apple)) {
                  result.add(apple);
              }
          });
          return result;
      }
      
    • negate (非)

      List<Apple> inventory = new ArrayList<>(Arrays.asList(
              new Apple("red", 15),
              new Apple("red", 10),
              new Apple("blue", 25),
              new Apple("black", 20)));
      
      // 筛选出不是红色的苹果
      Predicate<Apple> redApplePredicate = apple -> "red".equals(apple.getColor());
      List<Apple> appleList = filterApples(inventory, redApplePredicate.negate());
      // [Apple{color='blue', weight=25}, Apple{color='black', weight=20}]
      System.out.println(appleList);
      
    • and (且)

      List<Apple> inventory = new ArrayList<>(Arrays.asList(
              new Apple("red", 15),
              new Apple("red", 10),
              new Apple("blue", 25),
              new Apple("black", 20)));
      
      // 筛选出重量大于 10g 的红苹果
      Predicate<Apple> redApplePredicate = apple -> "red".equals(apple.getColor());
      Predicate<Apple> weightPredicate = apple -> apple.getWeight() > 10;
      List<Apple> appleList = filterApples(inventory, redApplePredicate.and(weightPredicate));
      // [Apple{color='red', weight=15}]
      System.out.println(appleList);
      
    • or (或)

      List<Apple> inventory = new ArrayList<>(Arrays.asList(
              new Apple("red", 15),
              new Apple("red", 10),
              new Apple("blue", 25),
              new Apple("black", 20)));
      
      // 筛选出红苹果或重量大于20g的苹果
      Predicate<Apple> redApplePredicate = apple -> "red".equals(apple.getColor());
      Predicate<Apple> weightPredicate = apple -> apple.getWeight() > 20;
      List<Apple> appleList = filterApples(inventory, redApplePredicate.or(weightPredicate));
      // [Apple{color='red', weight=15}, Apple{color='red', weight=10}, Apple{color='blue', weight=25}]
      System.out.println(appleList);
      
  • 函数复合

    • andThen

      • 返回一个组合函数,先对输入应用第一个函数,再对输出应用第二个函数 (先加后乘)

        // 先运算 1+1=2,再运算 2*2=4
        Function<Integer, Integer> plus = x -> x + 1;
        Function<Integer, Integer> mult = x -> x * 2;
        Function<Integer, Integer> andThen = plus.andThen(mult);
        System.out.println(andThen.apply(1)); // 4
        
    • compose

      • 返回一个组合函数,先对输入应用第二个函数,再对输出应用第一个函数 (先乘后加)

        // 先运算 1*2=2,再运算 2+1=3
        Function<Integer, Integer> plus = x -> x + 1;
        Function<Integer, Integer> mult = x -> x * 2;
        Function<Integer, Integer> compose = plus.compose(mult);
        System.out.println(compose.apply(1)); // 3
        
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值