如何在Java8里传递方法

假设你有一个Apple类,它有一个getColor方法,还有一个变量inventory保存着一个Apples列表。

你可能想要选出所有绿苹果(此处使用包含值GREEN和RED的Color枚举类型),并返回一个列表。

通常用筛选(filter)一词来表达这个概念。在java8之前,你可能会写这样一个方法:

public static List<Apple> filterGreenApples(List<Apple> inventory){
      List<Apple> result = new ArrayList<>();
      for (Apple apple:inventory){
          if(GREEN.equals(apple.getColor())){
              result.add(apple);
          }
      }
      return result;
}

但是接下来,有人可能想要选出重的苹果,比如超过150克的苹果,于是你心情沉重的写了下面这个方法,甚至用了复制粘贴:

public static List<Apple> filterHeavyApples(List<Apple> inventory){
      List<Apple> result = new ArrayList<>();
      for (Apple apple:inventory){
          if(apple.getWeight() > 150){//大于150克的苹果
              result.add(apple);
          }
      }
      return result;
}

嘿,这两个方法只有一行不同:if里面那行条件。如果这两个方法之间的差异仅仅是接受的重量范围不同,那么你只要把接受的重量上下限作为参数传递给filter就行了,比如指定(150,1000)来选出重的苹果(超过150克),或者指定(0,80)来选出轻的苹果(低于80克)。

但是,Java8会把条件代码作为参数传递进去,这样就可以避免filter方法中出现重复的代码。现在你可以这样写:

    public static boolean isGreenApple(Apple apple){
        return GREEN.equals(apple.getColor());
    }
    public static boolean isHeavyApple(Apple apple){
        return apple.getWeight > 150;
    }
    static List<Apple> filterApples(List<Apple> inventory,
                                    Predicate<Apple> p){ //方法作为Predicate参数p传递进去
        List<Apple> result = new ArrayList<>();
        for (Apple apple: inventory){
            if (p.test(apple)){ //该苹果符合p所代表的条件吗
                result.add(apple);
            }
        }
        return result;
    }    

调用它时,你可以这样写:

filterApples(inventory,Apple::isGreenApple);

或者:

filterApples(inventory,Apple::isHeavyApple);

现在你可以在Java8里传递方法了!

前面的代码传递了方法Apple::isGreenApple(它接受参数Apple,并返回一个boolean)给filterApples

后者则希望接受一个Predicate<Apple>参数。

Predicate<T>的解释:

谓词(predicate)在数学上常常用来代表类似于函数的东西,它接受一个参数值,并返回true或false

你会发现,Java8也允许你写Function<Apple,Boolean>————在学校学过函数却没学过谓词的读者对此可能更熟悉,但用Predicate<Apple>是更标准的方式,效率也会更高一点,这避免了把boolean封装在Boolean里面。


把方法作为值来传递显然很有用,但要是为类似于isGreenApple和isHeavyApple这种可能只用一两次的短方法写一堆定义就有点烦人了。不过Java8解决了这个问题,它引入了一套新记法(匿名函数或Lambda),让你可以这样写:

filterApples(inventory,(Apple a) -> GREEN.equals(a.getColor()));

或者:

filterApples(inventory,(Apple a) -> a.getWeight() > 150);

甚至:

filterApples(inventory,(Apple a) -> a.getWeight() < 80 ||
                                    RED.equals(a.getColor()));

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值