《Java 8 实战》 学习笔记一(行为参数化)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lms1719/article/details/52075592

  Java 8的新增功能相比以往的版本,发生了很大的变化。其中给我们带来的好处是,新功能提供的了强大的新词汇和新设计模式,能帮你编写更清楚、更简洁的代码。学习Java 8,我们要重点学习其中的Lambda表达式,下面的分析也主要根据Lambda来展开。


一、行为参数化的设计模式

我们先来看个例子(参考Java 8 实战):
1)我们帮果农做一个筛选绿苹果的功能,我们很可能是下面这样实现的:
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;
	}
2)然而要是果农想要筛选多种颜色,一种做法是给方法加一个参数,把颜色变成参数,这样就能灵活地适应变化了:
public static List<Apple> filterApplesByColor(List<Apple> inventory, String color){
		List<Apple> result = new ArrayList<>();
		for(Apple apple: inventory){
			if(apple.getColor().equals(color)){
				result.add(apple);
			}
		}
		return result;
	}
3)突然果农想要做个重量筛选,选出较重的苹果,作为程序员的你一般会想到下面的方法:
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;
	}
虽然上面的解决方案可以实现功能,但是你复制了大部分的代码来实现遍历库存,并对每个苹果应用筛选条件。这打破了DRY(Don't Repeat Yourself,不用重复自己)的软件工程原则,如果需要改变筛选方式,那就得修改所有的方法实现,这代价太大了。
我们再来看看先的实现方式:
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}]
	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);
           
这就是将行为(函数)作为参数进行传递,这样可以更好地应对不断变化的需求。

上面的代码在Java 8 里可以用Lambda表达式重下为下面的样子:
List<Apple> result = filterApples(inventory, (Apple apple) -> "red".equals(apple.getColors()));
不得不承认这代码看上去比以前的干净了很多。


猜你喜欢

转载自blog.csdn.net/lms1719/article/details/52075592