需求根据颜色和重量选出需要的苹果:
选出绿色的苹果:方案一
package lambdasinaction.chap2;
import java.util.*;
public class FilteringApples{
public static void main(String [] args){
List<Apple> inventory = Arrays.asList(new Apple(80,"green"),
new Apple(155, "green"), new Apple(120, "red"));
List<Apple> filterGreenApples = filterGreenApples(inventory);
System.out.println(filterGreenApples);
}
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;
}
public static 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 +
'}';
}
}
}
输出结果是
[Apple{color='green', weight=80}, Apple{color='green', weight=155}]
如果需要变更要求有更多颜色要求加入
public static void main(String[] args) {
List<Apple> inventory = Arrays.asList(new Apple(80, "green"),
new Apple(155, "green"), new Apple(120, "red"));
List<Apple> filterGreenApples = filterGreenApples(inventory,"red");
System.out.println(filterGreenApples);
}
public static List<Apple> filterGreenApples(List<Apple> inventory,String color) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if (color.equals(apple.getColor())) {
result.add(apple);
}
}
return result;
}
如果需要再次变更,要求不仅有颜色限制还要有重量的限制加入,加入如下代码:
public static List<Apple> filterApplesByWeight(List<Apple> inventory, int weight){
List<Apple> result = new ArrayList<>();
for(Apple apple: inventory){
if(apple.getWeight() > weight){
result.add(apple);
}
}
return result;
}
如果两者都要进行限制还判断起来就比较麻烦,
public static List<Apple> filterApplesByWeight(List<Apple> inventory, int weight,String color,boolean falg){
List<Apple> result = new ArrayList<>();
for(Apple apple: inventory){
if((flag && apple.getWeight() > weight) || (apple.getColor().equals(color))){
result.add(apple);
}
}
return result;
}
这个解决方案很差,很糟糕。拓展性也十分的差。如果后面在加上产地、形状等一系列条件就会变成十分复杂的组合了。
行为参数化
对选择标准建模(更高层次的抽象)——策略设计模式:定义一族算法,把他们封装起来,然后在运行是选择一个算法。在此时filterApples 方法的行为参数化了。
package lambdasinaction.chap2;
import java.util.*;
public class FilteringApples{
public static void main(String [] args){
List<Apple> inventory = Arrays.asList(new Apple(80,"green"),
new Apple(155, "green"), new Apple(120, "red"));
// [Apple{color='green', weight=80}, Apple{color='green', weight=155}]
List<Apple> greenApples2 = filter(inventory, new AppleColorPredicate());
System.out.println(greenApples2);
// [Apple{color='green', weight=155}]
List<Apple> heavyApples = filter(inventory, new AppleWeightPredicate());
System.out.println(heavyApples);
// []
List<Apple> redAndHeavyApples = filter(inventory, new AppleRedAndHeavyPredicate());
System.out.println(redAndHeavyApples);
}
public static List<Apple> filter(List<Apple> inventory, ApplePredicate p){
List<Apple> result = new ArrayList<>();
for(Apple apple : inventory){
if(p.test(apple)){
result.add(apple);
}
}
return result;
}
public static 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 +
'}';
}
}
interface ApplePredicate{
public boolean test(Apple a);
}
static class AppleWeightPredicate implements ApplePredicate{
public boolean test(Apple apple){
return apple.getWeight() > 150;
}
}
static class AppleColorPredicate implements ApplePredicate{
public boolean test(Apple apple){
return "green".equals(apple.getColor());
}
}
static class AppleRedAndHeavyPredicate implements ApplePredicate{
public boolean test(Apple apple){
return "red".equals(apple.getColor())
&& apple.getWeight() > 150;
}
}
}
执行结果
[Apple{color='green', weight=80}, Apple{color='green', weight=155}]
[Apple{color='green', weight=155}]
[]
针对上一篇文章使用行为参数化:用谓词筛选苹果,已经有了很大的改善。但是能不能做的跟好呢?
Java 有一个机制称为匿名类,它可以让你同时声明和实例化一个类。可以帮这你进一步改善代码。
package lambdasinaction.chap2;
import java.util.*;
public class FilteringApples{
public static void main(String [] args){
List<Apple> inventory = Arrays.asList(new Apple(80,"green"),
new Apple(155, "green"), new Apple(120, "red"));
// [Apple{color='red', weight=120}]
List<Apple> redApples2 = filter(inventory, new ApplePredicate() {
public boolean test(Apple a){
return a.getColor().equals("red");
}
});
System.out.println(redApples2);
}
public static List<Apple> filter(List<Apple> inventory, ApplePredicate p){
List<Apple> result = new ArrayList<>();
for(Apple apple : inventory){
if(p.test(apple)){
result.add(apple);
}
}
return result;
}
public static 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 +
'}';
}
}
interface ApplePredicate{
public boolean test(Apple a);
}
}
输出结果
[Apple{color='red', weight=120}]