假設有如下業(yè)務:有一堆有顏色和重量的蘋果,我需要通過顏色和重量取出相應蘋果
定義蘋果
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:
List<Apple> result = new ArrayList<>();
for(Apple apple: inventory){
if("green".equals(apple.getColor())){
result.add(apple);
}
}
這是最常見的方法掌测。但是這樣的結構很難復用内贮。比如我顏色不確定呢?
解決方案2:
List<Apple> result = new ArrayList<>();
for(Apple apple: inventory){
if(apple.getColor().equals(color)){
result.add(apple);
}
}
如果我需要100g以上的且紅色的蘋果我就需要
List<Apple> result = new ArrayList<>();
for(Apple apple: inventory){
if(apple.getColor().equals(color)
&& apple.getWeight() > weight){
result.add(apple);
}
}
如果我需要100g以上或者紅色的蘋果
List<Apple> result = new ArrayList<>();
for(Apple apple: inventory){
if(apple.getColor().equals(color)
|| apple.getWeight() > weight){
result.add(apple);
}
}
是不是變得沒完沒了了?
解決方案3:
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;
}
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;
}
}
List<Apple> greenApples2 = filterApples(inventory, new AppleColorPredicate());
這種方法和合適夜郁。不過如果規(guī)則也是不確定的呢什燕?
解決方案4:
List<Apple> redApples2 = filterApples(inventory, new ApplePredicate() {
public boolean test(Apple a){
return a.getColor().equals("red");
}
});
Good!這樣就能做到定制化了。不過通過lambda寫起來更加優(yōu)美
解決方案5:
List<Apple> redApples2 = filterApples(inventory, (Apple a)-> a.getColor().equals("red"));
如果我們要推廣竞端。不只是蘋果而是所有的判斷規(guī)則屎即?
解決方案6:
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;
}
List<Apple> redApples2 = filter(inventory, (Apple a)-> a.getColor().equals("red"));
其實java 8 的思路也是這樣的
解決方案7:
List<Apple> redApples2 = inventory
.stream()
.filter((Apple a)-> a.getColor().equals("red"))
.collect(Collectors.toList());