我想基于谓词过滤java.util.Collection
。
#1楼
JFilter http://code.google.com/p/jfilter/最适合您的要求。
JFilter是一个简单且高性能的开源库,用于查询Java Bean的集合。
主要特征
- 支持集合(java.util.Collection,java.util.Map和Array)属性。
- 支持集合内任何深度的集合。
- 支持内部查询。
- 支持参数化查询。
- 可以在几百毫秒内过滤一百万条记录。
- 过滤器(查询)以简单的json格式给出,就像Mangodb查询一样。 以下是一些示例。
- {“ id”:{“ $ le”:“ 10”}
- 其中对象id属性小于等于10。
- {“ id”:{“ $ in”:[“ 0”,“ 100”]}}
- 其中对象id属性为0或100。
- {“ lineItems”:{“ lineAmount”:“ 1”}}
- 其中参数化类型的lineItems集合属性的lineAmount等于1。
- {“ $ and”:[{“ id”:“ 0”},{“ billingAddress”:{“ city”:“ DEL”}}]}
- 其中id属性为0,billingAddress.city属性为DEL。
- {“ lineItems”:{“ taxes”:{“ key”:{“ code”:“ GST”},“ value”:{“ $ gt”:“ 1.01”}}}}
- 其中参数化类型的具有税款映射类型的参数化类型的lineItems集合属性的代码等于GST值大于1.01。
- {'$ or':[{'code':'10'},{'skus':{'$ and':[{'price':{'$ in':['20','40']} },{'code':'RedApple'}]}}]}
- 选择产品代码为10或sku价格为20和40且sku代码为“ RedApple”的所有产品。
#2楼
使用集合查询引擎(CQEngine) 。 到目前为止,这是最快的方法。
另请参阅: 如何查询Java中的对象集合(类似于Criteria / SQL)?
#3楼
使用来自Apache Commons的CollectionUtils.filter(Collection,Predicate) 。
#4楼
考虑将Google Collections用于支持泛型的更新的Collections框架。
更新 :谷歌收藏库现已弃用。 您应该使用最新版本的Guava 。 它仍然具有对集合框架的所有相同扩展,包括基于谓词进行过滤的机制。
#5楼
您确定要过滤Collection本身,而不是迭代器吗?
参见org.apache.commons.collections.iterators.FilterIterator
或使用Apache Commons org.apache.commons.collections4.iterators.FilterIterator的第4版
#6楼
设置:
public interface Predicate<T> {
public boolean filter(T t);
}
void filterCollection(Collection<T> col, Predicate<T> predicate) {
for (Iterator i = col.iterator(); i.hasNext();) {
T obj = i.next();
if (predicate.filter(obj)) {
i.remove();
}
}
}
用法:
List<MyObject> myList = ...;
filterCollection(myList, new Predicate<MyObject>() {
public boolean filter(MyObject obj) {
return obj.shouldFilter();
}
});
#7楼
“最佳”方式要求太高。 它是“最短的”吗? “最快的”? “可读”? 过滤到位还是进入另一个集合?
最简单(但不是最易读)的方法是对其进行迭代并使用Iterator.remove()方法:
Iterator<Foo> it = col.iterator();
while( it.hasNext() ) {
Foo foo = it.next();
if( !condition(foo) ) it.remove();
}
现在,为了使其更具可读性,您可以将其包装为实用程序方法。 然后发明一个IPredicate接口,创建该接口的匿名实现并执行以下操作:
CollectionUtils.filterInPlace(col,
new IPredicate<Foo>(){
public boolean keepIt(Foo foo) {
return foo.isBar();
}
});
其中filterInPlace()迭代集合并调用Predicate.keepIt()来了解实例是否要保留在集合中。
我真的没有理由为此目的引入第三方库。
#8楼
假设您使用的是Java 1.5 ,并且无法添加Google Collections ,那么我将执行与Google员工非常相似的操作。 这与乔恩的评论略有不同。
首先将此接口添加到您的代码库中。
public interface IPredicate<T> { boolean apply(T type); }
它的实现者可以在某个谓词为某种类型的真时回答。 例如,如果T
是User
并且AuthorizedUserPredicate<User>
实现IPredicate<T>
,则AuthorizedUserPredicate#apply
返回传入的User
是否被授权。
然后在某些实用程序类中,您可以说
public static <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) {
Collection<T> result = new ArrayList<T>();
for (T element: target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
因此,假设您已使用上述方法,
Predicate<User> isAuthorized = new Predicate<User>() {
public boolean apply(User user) {
// binds a boolean method in User to a