假设有如下业务:有一堆有颜色和重量的苹果,我需要通过颜色和重量取出相应苹果
定义苹果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 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 + '}'; } }
|
假设
1 2
| inventory = Arrays.asList(new Apple(80,"green"), new Apple(155, "green"), new Apple(120, "red"));
|
解决方案1:
1 2 3 4 5 6
| List<Apple> result = new ArrayList<>(); for(Apple apple: inventory){ if("green".equals(apple.getColor())){ result.add(apple); } }
|
这是最常见的方法。但是这样的结构很难复用。比如我颜色不确定呢?
解决方案2:
1 2 3 4 5 6
| List<Apple> result = new ArrayList<>(); for(Apple apple: inventory){ if(apple.getColor().equals(color)){ result.add(apple); } }
|
如果我需要100g以上的且红色的苹果我就需要
1 2 3 4 5 6 7
| List<Apple> result = new ArrayList<>(); for(Apple apple: inventory){ if(apple.getColor().equals(color) && apple.getWeight() > weight){ result.add(apple); } }
|
如果我需要100g以上或者红色的苹果
1 2 3 4 5 6 7
| List<Apple> result = new ArrayList<>(); for(Apple apple: inventory){ if(apple.getColor().equals(color) || apple.getWeight() > weight){ result.add(apple); } }
|
是不是变得没完没了了?
解决方案3:
1 2 3 4 5 6 7 8 9
| public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p){ List<Apple> result = new ArrayList<>(); for(Apple apple : inventory){ if(p.test(apple)){ result.add(apple); } } return result; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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; } }
|
1
| List<Apple> greenApples2 = filterApples(inventory, new AppleColorPredicate());
|
这种方法和合适。不过如果规则也是不确定的呢?
解决方案4:
1 2 3 4 5
| List<Apple> redApples2 = filterApples(inventory, new ApplePredicate() { public boolean test(Apple a){ return a.getColor().equals("red"); } });
|
Good!这样就能做到定制化了。不过通过lambda写起来更加优美
解决方案5:
1 2
| List<Apple> redApples2 = filterApples(inventory, (Apple a)-> a.getColor().equals("red"));
|
如果我们要推广。不只是苹果而是所有的判断规则?
解决方案6:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| interface Predicate<T>{ boolean test(T t); }
public static <T> List<T> filter(List<T> inventory, Predicate<T> p){ List<T> result = new ArrayList<>(); for(T apple : inventory){ if(p.test(apple)){ result.add(apple); } } return result; }
|
1
| List<Apple> redApples2 = filter(inventory, (Apple a)-> a.getColor().equals("red"));
|
其实java 8 的思路也是这样的
解决方案7:
1 2 3 4
| List<Apple> redApples2 = inventory .stream() .filter((Apple a)-> a.getColor().equals("red")) .collect(Collectors.toList());
|