假设有如下业务:有一堆有颜色和重量的苹果,我需要通过颜色和重量取出相应苹果 定义苹果
public class Apple { private int weight = 0; private String color = ""; public Apple(int weight, String color){ this.weight = weight; this.color = color; } public Integer getWeight() { return weight; } public void setWeight(Integer weight) { this.weight = weight; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public String toString() { return "Apple{" + "color='" + color + '\'' + ", weight=" + weight + '}'; } }复制代码
假设
inventory = Arrays.asList(new Apple(80,"green"), new Apple(155, "green"), new Apple(120, "red"));复制代码
解决方案1:
Listresult = new ArrayList<>(); for(Apple apple: inventory){ if("green".equals(apple.getColor())){ result.add(apple); } }复制代码
这是最常见的方法。但是这样的结构很难复用。比如我颜色不确定呢?
解决方案2:
Listresult = new ArrayList<>(); for(Apple apple: inventory){ if(apple.getColor().equals(color)){ result.add(apple); } }复制代码
如果我需要100g以上的且红色的苹果我就需要
Listresult = new ArrayList<>(); for(Apple apple: inventory){ if(apple.getColor().equals(color) && apple.getWeight() > weight){ result.add(apple); } }复制代码
如果我需要100g以上或者红色的苹果
Listresult = new ArrayList<>(); for(Apple apple: inventory){ if(apple.getColor().equals(color) || apple.getWeight() > weight){ result.add(apple); } }复制代码
是不是变得没完没了了? 解决方案3:
public static ListfilterApples(List inventory, ApplePredicate p){ List result = new ArrayList<>(); for(Apple apple : inventory){ if(p.test(apple)){ result.add(apple); } } return result; }复制代码
interface ApplePredicate{ boolean test(Apple a); } class AppleWeightPredicate implements ApplePredicate{ public boolean test(Apple apple){ return apple.getWeight() > 150; } } class AppleColorPredicate implements ApplePredicate{ public boolean test(Apple apple){ return "green".equals(apple.getColor()); } } class AppleRedAndHeavyPredicate implements ApplePredicate{ public boolean test(Apple apple){ return "red".equals(apple.getColor()) && apple.getWeight() > 150; } }复制代码
ListgreenApples2 = filterApples(inventory, new AppleColorPredicate());复制代码
这种方法和合适。不过如果规则也是不确定的呢?
解决方案4:
ListredApples2 = filterApples(inventory, new ApplePredicate() { public boolean test(Apple a){ return a.getColor().equals("red"); } });复制代码
Good!这样就能做到定制化了。不过通过lambda写起来更加优美
解决方案5:
ListredApples2 = filterApples(inventory, (Apple a)-> a.getColor().equals("red")); 复制代码
如果我们要推广。不只是苹果而是所有的判断规则?
解决方案6:
interface Predicate{ boolean test(T t); } public static List filter(List inventory, Predicate p){ List result = new ArrayList<>(); for(T apple : inventory){ if(p.test(apple)){ result.add(apple); } } return result; } 复制代码
ListredApples2 = filter(inventory, (Apple a)-> a.getColor().equals("red"));复制代码
其实java 8 的思路也是这样的 解决方案7:
ListredApples2 = inventory .stream() .filter((Apple a)-> a.getColor().equals("red")) .collect(Collectors.toList());复制代码