在Java8之前,想想我们的方法可以传递什么作为参数呢?变量以及对象的引用或者接口的引用。但是没有吧方法或者方法的引用作为参数进行传递。比如说我们要判断某个文件目录下面是否存在隐藏文件,在8之前我们通常是如下的做法:
File file=new File(".");
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isHidden();
}
});
通过文件过滤FileFilter的accept方法,然后调用isHidden()方法实现,但是在Java8中只有一行代码:
file.listFiles(File::isHidden)
我们看看整个这样写法的进化过程(注:引用的代码以及案例均在Java8实战这本书上)
需求1:我们要帅选绿色的苹果,我们的方法是如下的代码:
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;
}
需求2:帅选大于150g的苹果:
public static List<Apple> filterHeavyApples(List<Apple> inventory){
List<Apple> result = new ArrayList<>();
for (Apple apple: inventory){
if (apple.getWeight() > 150) {
result.add(apple);
}
}
return result;
}
上面两个方法仅有帅选条件不同,其余代码基本一致。那么如何改进呢。当然通过设计模式还是可以实现的。定义一个接口,并且存在帅选的条件方法。但是巧的是没有接口或者不想写接口呢?下面是我们的实现:
Apple类:
public class Apple {
private int weight;
private String color;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public static boolean isGreenApple(Apple apple) {
return "green".equals(apple.getColor());
}
public static boolean isHeavyApple(Apple apple) {
return apple.getWeight() > 150;
}
}
public interface Predicate<T>{
boolean test(T t);
}
帅选数据集合:
static List<Apple> filterApples(List<Apple> inventory,
Predicate<Apple> p) {
List<Apple> result = new ArrayList<>();
for (Apple apple: inventory){
if (p.test(apple)) {
result.add(apple);
}
}
return result;
}
测试:
public static void main(String[] args) {
List<Apple> inventory=new ArrayList<>();
//原始
filterApples(inventory,Apple::isGreenApple);
filterApples(inventory,Apple::isHeavyApple);
//Stream API用法
inventory.stream().filter(Apple::isGreenApple);
inventory.stream().filter(Apple::isHeavyApple);
}
同样的上述测试也可以使用Lamada表达式实现:
public static void main(String[] args) {
List<Apple> inventory=new ArrayList<>();
filterApples(inventory,Apple::isGreenApple);
filterApples(inventory,(Apple a)->"green".equals(a.getColor()));
filterApples(inventory,(Apple a)-> a.getWeight()>150);
//多条件筛选
filterApples(inventory,(Apple a)-> a.getWeight()>150 || "green".equals(a.getColor()));
inventory.stream().filter(Apple::isGreenApple);
inventory.stream().filter(Apple::isHeavyApple);
}