在一小节中,我们有两个需求:
1、从一筐苹果中筛选出红色的苹果;
2、从一筐苹果中筛选出重的苹果;
好了,首先先来定义苹果:
public class Apple { public Apple() { } public Apple(String color, int weight) { this.color = color; this.weight = weight; } private String color; // 颜色 private int weight; // 重量 //这里省略了color、weight的getter和setter方法。 public static boolean filterRedApple(Apple apple) { return "red".equals(apple.getColor()); } public static boolean filterWeightApple(Apple apple) { return apple.getWeight() > 150; } @Override public String toString() { return "Apple [color=" + color + ", weight=" + weight + "]"; }}
我们可以看到filterRedApple方法和filterWeightApple方法;这两个方法参数是Apple,返回boolean。
在这两个方法中,只是简单的做了判断。如果是有用的数据,就返回true。(偷偷的告诉你,返回true的数据都是有用的,就就像Collections.sort()方法一样。)
好了,如果两个方法看不懂为啥,就别纠结了,看下面:
public static ListfilterApple(List apples, Predicate predicate) { ArrayList result = new ArrayList (); for (Apple apple : apples) { if (predicate.test(apple)) { result.add(apple); } } return result; }
这个static方法,获得一筐苹果(List<Apple>),返回筛选符合'要求'的苹果;在这里看到了另一个参数:Predicate<Apple> predicate,看方法体:if (predicate.test(apple)),也就是这个对象去测试这个苹果,看这个苹果是不是符合'要求',符合要求返回true;那Predicate<Apple>到底是什么鬼呢?
public interface Predicate{ /** * Evaluates this predicate on the given argument. * * @param t * the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */ boolean test(T t); }
其实就是一个接口中,有个test方法去测试<T>是否符合要求,因为这里泛型<T>是Apple,所以就是测试Apple,返回boolean。
接下来就是使用filterApple()方法去筛选符合'要求'的苹果了,慢着,'符合要求'到底是符合什么要求?呵呵,还记得前面两个方法吗?
public static boolean filterRedApple(Apple apple) { return "red".equals(apple.getColor()); } public static boolean filterWeightApple(Apple apple) { return apple.getWeight() > 150; }
恩,这就是'要求'。然后我们就要有一筐苹果:
ArrayListapples = new ArrayList (); apples.add(new Apple("red", 21)); apples.add(new Apple("green", 66)); apples.add(new Apple("black", 146)); apples.add(new Apple("red", 156)); apples.add(new Apple("red", 95)); apples.add(new Apple("green", 200));
然后看最前面的需求1:从一筐苹果中筛选出红色的苹果;
List所有红色的苹果 = filterApple(apples, Apple::filterRedApple);
需求2:从一筐苹果中筛选出重的苹果;
List所有重的苹果 = filterApple(apples, Apple::filterWeightApple);
把符合筛选调节的结果展示给大家:
System.out.println("所有红色的苹果:\t" + 所有红色的苹果); System.out.println("所有重的苹果:\t" + 所有重的苹果);
大家看到的结果:
所有红色的苹果: [Apple [color=red, weight=21], Apple [color=red, weight=156], Apple [color=red, weight=95]]所有重的苹果: [Apple [color=red, weight=156], Apple [color=green, weight=200]]
不知道大家看明白没有。。。我猜肯定没有吧。因为我现在还晕着,虽然这样写是正确的;而且也更符合需求的表达方式。那么到底是怎么回事呢?请看《java8实战》第1.2.2小节。
最后把代码都写在下面:
首先是Apple类:
package com.test.java8.lambda;public class Apple { public Apple() { } public Apple(String color, int weight) { this.color = color; this.weight = weight; } private String color; private int weight; public String getColor() { return color; } public void setColor(String color) { this.color = color; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } public static boolean filterRedApple(Apple apple) { return "red".equals(apple.getColor()); } public static boolean filterWeightApple(Apple apple) { return apple.getWeight() > 150; } @Override public String toString() { return "Apple [color=" + color + ", weight=" + weight + "]"; }}
测试的类:FilterAppleTest
import java.util.ArrayList;import java.util.List;public class FilterAppleTest { public static void main(String[] args) { ArrayListapples = new ArrayList (); apples.add(new Apple("red", 21)); apples.add(new Apple("green", 66)); apples.add(new Apple("black", 146)); apples.add(new Apple("red", 156)); apples.add(new Apple("red", 95)); apples.add(new Apple("green", 200)); List 所有红色的苹果 = filterApple(apples, Apple::filterRedApple); List 所有重的苹果 = filterApple(apples, Apple::filterWeightApple); System.out.println("所有红色的苹果:\t" + 所有红色的苹果); System.out.println("所有重的苹果:\t" + 所有重的苹果); // 这个在上面没有讲,我是想:判断一个苹果是不是红色的。就这样 boolean isRed = isRed(new Apple("green", 555), (a) -> "red".equals(a.getColor())); System.out.println("isRed:\t" + isRed); } public static boolean isRed(Apple apple, Predicate fun) { return fun.test(apple); } public static List filterApple(List apples, Predicate predicate) { ArrayList result = new ArrayList (); for (Apple apple : apples) { if (predicate.test(apple)) { result.add(apple); } } return result; } public interface Predicate { /** * Evaluates this predicate on the given argument. * * @param t * the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */ boolean test(T t); }}
最后说一下,其实 interface Predicate<T> 是java.util.function.Predicate;这个接口,因为这个接口中不止test()一个方法,所以我把这个接口和这个方法拿出来了。为了看的更清楚。
对于Predicate,《Java8实战》这这样说道:
什么是谓词? 谓词,在数学上常常用来表示一个类似函数的东西,它接收一个参数值,并返回true或false。 这里我们用谓词当做一个方法,接收一个苹果,返回一个true或false。 到底返回的是true还是false,就看filterRedApple()方法或者filterWeightApple()方法了。
好了,睡觉。