在Java中过滤java.util.Collection

时间:2010-09-30 14:44:40

标签: java collections

我写了一个util类来过滤java.util.Collection中的元素,如下所示:

public class Util{
  public static <T> void filter(Collection<T> l, Filter<T> filter) {
    Iterator<T> it= l.iterator();
    while(it.hasNext()) {
      if(!filter.match(it.next())) {
        it.remove();
      }
    }
  }
}

public interface Filter<T> {
  public boolean match(T o);
}

问题:

  1. 您认为有必要编写方法吗?
  2. 有关方法的任何改进?

7 个答案:

答案 0 :(得分:5)

您应该允许任何Filter<? super T>而不仅仅是Filter<T>

客户端可能还希望拥有一个返回新Collection的方法:

public static <T> Collection<T> filter(Collection<T> unfiltered, 
    Filter<? super T> filter)

答案 1 :(得分:4)

  1. 否。 guava-libraries已具备此功能。请参阅Predicate实施过滤的Iterables.filter(iterableCollection, predicate)

答案 2 :(得分:1)

是否有必要取决于你想要达到的目标。如果您可以使用其他第三方库,例如Google Collections,那么没有。如果它计划是一次性的,那么可能不是。如果你计划创建不同的过滤器,那么,看起来是一种保持模块化和凝聚力的好方法。

一个建议 - 您可能想要返回一个Collection - 这样,您可以选择返回一个新的过滤Collection而不是改变原始Collection。如果你需要在并发环境中使用它,这可能很方便。

您还可以查看对{​​{3}}的回复。

答案 3 :(得分:1)

看起来不错 - 但我们无法决定,是否“必须”编写它(好吧,你真的写了它;)

remove()方法并非始终实施,而是标记为(可选)。一些迭代器只抛出UnsupportedOperationException。您应该捕获它或将其转换为自定义异常,说明此集合无法过滤。

然后您可以将方法签名更改为

public static <T> void filter(Iterable<T> i, Filter<T> filter)

因为迭代器不仅限于集合。使用此实用程序方法,您可以过滤每个提供迭代器的“容器”,该迭代器允许删除操作。

答案 4 :(得分:1)

  
    

您认为有必要编写方法吗?

  

如果你不介意使用第三方库,那么不。

提供此功能的第三方库的一些建议:

您可能希望查看提供filter的{​​{3}}以及真蓝色函数式语言中的许多其他高阶函数。

示例:

List<Person> adults = filter(people, new F1<Person, Boolean>() {
  public Boolean f(Person p) {
    return p.getAge() > 18;
  }
});

另一种选择是使用Functional Java - 一个具有相似目标但比功能Java更简洁的库。 lambdaj并没有像Functional Java那样覆盖那么多。

示例:

List<Person> adults = filter(having(on(Person.class).getAge(), greaterThan(18)), people);

答案 5 :(得分:1)

关于问题1,已经有很多集合库。实例通过apache common-collections CollectionUtils和google collections Iterables提供过滤。

答案 6 :(得分:0)

我认为在visit(T o)界面中定义Filter<T>方法会很酷。这样,过滤器实现可以决定在匹配时对访问对象采取什么操作。