过滤器也是一种结构型模式,它允许我们使用不同的规则过滤某一组对象。
首先我们来编写一个实体类,用作被过滤的对象。
public class Person {
private int age;
private String name;
private Gender gender;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Person{");
sb.append("age=").append(age);
sb.append(", name='").append(name).append('\'');
sb.append(", gender=").append(gender);
sb.append('}');
return sb.toString();
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Person(int age, String name, Gender gender) {
this.age = age;
this.name = name;
this.gender = gender;
}
}
enum Gender {
Male, Female
}
然后来编写过滤器。这里编写了两个过滤器,过滤年龄和性别的。还编写了一个与过滤器,用于同时应用两个过滤器。
public interface Filter {
List<Person> filter(List<Person> people);
}
class AgeGreaterThan20Filter implements Filter {
@Override
public List<Person> filter(List<Person> people) {
List<Person> result = new ArrayList<>();
for (Person p : people) {
if (p.getAge() > 20) {
result.add(p);
}
}
return result;
}
}
class FemaleFilter implements Filter {
@Override
public List<Person> filter(List<Person> people) {
List<Person> result = new ArrayList<>();
for (Person p : people) {
if (p.getGender() == Gender.Female) {
result.add(p);
}
}
return result;
}
}
class AndFilter implements Filter {
private Filter one;
private Filter other;
public AndFilter(Filter one, Filter other) {
this.one = one;
this.other = other;
}
@Override
public List<Person> filter(List<Person> people) {
List<Person> tmp = one.filter(people);
return other.filter(tmp);
}
}
之后来测试一下。我们可以看到,由于过滤器和实体类解耦,所以我们可以随便使用过滤器来处理数据。
List<Person> people = new ArrayList<>();
people.add(new Person(22, "yitian", Gender.Male));
people.add(new Person(23, "zhang3", Gender.Female));
people.add(new Person(24, "li4", Gender.Male));
people.add(new Person(25, "wang5", Gender.Female));
people.add(new Person(13, "zhao6", Gender.Male));
people.add(new Person(10, "fuck", Gender.Female));
Filter femaleFilter = new FemaleFilter();
List<Person> women = femaleFilter.filter(people);
System.out.println("女人们:" + women);
Filter ageGreaterThan20Filter = new AgeGreaterThan20Filter();
List<Person> gt20 = ageGreaterThan20Filter.filter(people);
System.out.println("大于20的人:" + gt20);
Filter andFilter = new AndFilter(femaleFilter, ageGreaterThan20Filter);
System.out.println("既是女性有大于20的人:" + andFilter.filter(people));
如果使用过Java 8的话会发现lambda表达式和流类库会帮我们非常方便的实现过滤器模式的功能。
//lambda表达式
List<Person> men = people.stream()
.filter(o -> o.getGender() == Gender.Male)
.filter(o -> o.getAge() >= 23)
.collect(Collectors.toList());
System.out.println("大于23的男性:" + men);
通过新的语言特性,我们可以简化设计模式的使用,更快速的开发程序。当然,了解设计模式还是很有必要的。领会设计模式的思想,可以让我们更深刻的理解程序设计的奥秘,对我们学习编程还是很有帮助的。