读书笔记03——Java 8 实战——(第二章:通过行为参数化传递代码)

需求根据颜色和重量选出需要的苹果:

选出绿色的苹果:方案一

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}]

猜你喜欢

转载自blog.csdn.net/haochaoguo1988/article/details/81537088
今日推荐