过滤Java集合的最佳方法是什么?

我想基于谓词过滤java.util.Collection 。
摘要由CSDN通过智能技术生成

我想基于谓词过滤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); }

它的实现者可以在某个谓词为某种类型的真时回答。 例如,如果TUser并且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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值