📜  Java的过滤器模式(1)

📅  最后修改于: 2023-12-03 14:43:03.062000             🧑  作者: Mango

Java的过滤器模式

过滤器模式是一种设计模式,它允许我们使用不同的条件过滤一组对象,以便获取所需的子集。该模式封装了生成的过滤器以及它们应该被应用的对象,使得代码有更高的可重用性和可扩展性。Java中的过滤器模式有多种使用方式,下面我们将结合代码片段给出一些使用方法。

基本概念

在Java中,过滤器模式通常由两个类组成:过滤器接口和实现该接口的过滤器类。这些类通常涉及以下概念:

过滤器接口

该接口定义了一个名为filter的方法,它将一个对象作为参数,并根据实现细节确定是否应该过滤该对象。如果对象通过了过滤器的检查,该方法应该返回true,否则应该返回false。以下是一个示例接口:

public interface Filter<T> {
    boolean filter(T t);
}
过滤器类

过滤器类实现过滤器接口,并具有实施确定是否过滤对象的逻辑。以下是一个示例过滤器类:

public class AgeFilter implements Filter<Person> {
    private int age;
    
    public AgeFilter(int age) {
        this.age = age;
    }
    
    public boolean filter(Person person) {
        return person.getAge() >= age;
    }
}
使用示例
过滤器链

过滤器链是一种通用的方式,用于同时将多个过滤器应用于对象。在Java中,我们可以通过创建一个包含多个过滤器的链来实现这一点。以下是一个示例链:

public class FilterChain<T> implements Filter<T> {
    private List<Filter<T>> filters;
    
    public FilterChain() {
        this.filters = new ArrayList<>();
    }
    
    public void addFilter(Filter<T> filter) {
        filters.add(filter);
    }
    
    public boolean filter(T t) {
        for (Filter<T> filter : filters) {
            if (!filter.filter(t)) {
                return false;
            }
        }
        
        return true;
    }
}

我们可以使用上面的链来筛选Person对象列表。以下是使用示例:

FilterChain<Person> filterChain = new FilterChain<>();
filterChain.addFilter(new AgeFilter(18));
filterChain.addFilter(new NameFilter("Tom"));

List<Person> persons = Arrays.asList(
    new Person("Tom", 18),
    new Person("Lucy", 19),
    new Person("Tom", 21)
);

List<Person> filteredPersons = persons.stream()
    .filter(filterChain::filter)
    .collect(Collectors.toList());

上面的代码将基于年龄和姓名过滤Person对象列表,最终返回符合条件的Person对象列表。

过滤器组合

在某些情况下,我们可能需要以某种方式组合过滤器,例如使用逻辑运算符(AND,OR等)进行组合。以下是一个示例组合器:

public class LogicalCompositeFilter<T> implements Filter<T> {
    private List<Filter<T>> filters;
    private String operation;
    
    public LogicalCompositeFilter(String operation) {
        this.filters = new ArrayList<>();
        this.operation = operation;
    }
    
    public void addFilter(Filter<T> filter) {
        filters.add(filter);
    }
    
    public boolean filter(T t) {
        if (operation.equals("AND")) {
            for (Filter<T> filter : filters) {
                if (!filter.filter(t)) {
                    return false;
                }
            }
            
            return true;
        } else if (operation.equals("OR")) {
            for (Filter<T> filter : filters) {
                if (filter.filter(t)) {
                    return true;
                }
            }
            
            return false;
        }
        
        return false;
    }
}

我们可以使用上面的组合器来组合多个年龄和姓名过滤器的结果。以下是使用示例:

LogicalCompositeFilter<Person> andFilter = new LogicalCompositeFilter<>("AND");
andFilter.addFilter(new AgeFilter(18));
andFilter.addFilter(new NameFilter("Tom"));

LogicalCompositeFilter<Person> orFilter = new LogicalCompositeFilter<>("OR");
orFilter.addFilter(new AgeFilter(18));
orFilter.addFilter(new NameFilter("Lucy"));

List<Person> persons = Arrays.asList(
    new Person("Tom", 18),
    new Person("Lucy", 19),
    new Person("Tom", 21)
);

List<Person> filteredPersons = persons.stream()
    .filter(andFilter::filter)
    .collect(Collectors.toList());

List<Person> filteredPersons2 = persons.stream()
    .filter(orFilter::filter)
    .collect(Collectors.toList());

上面的代码将基于年龄和姓名过滤Person对象列表,并返回符合条件的Person对象列表。我们可以根据特定需求选择要使用的过滤器组合器,以获得所需的结果。