我写了一个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);
}
问题:
答案 0 :(得分:5)
您应该允许任何Filter<? super T>
而不仅仅是Filter<T>
。
客户端可能还希望拥有一个返回新Collection的方法:
public static <T> Collection<T> filter(Collection<T> unfiltered,
Filter<? super T> filter)
答案 1 :(得分:4)
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>
方法会很酷。这样,过滤器实现可以决定在匹配时对访问对象采取什么操作。