Java:如何用大量谓词过滤大量对象?

Java:如何用大量谓词过滤大量对象?,java,collections,predicate,Java,Collections,Predicate,在Java中,我有一个大对象集合(~10000个对象),比如Set cityinhabitats。我还有一个很大的谓词集合(~1000个谓词),用于过滤匹配这些谓词的任何Person。例如,谓词可以是 person.getName().equals(“丑陋的名字1”) person.getName().equals(“丑陋的名字2”) person.getAge()

在Java中,我有一个大对象集合(~10000个对象),比如
Set cityinhabitats
。我还有一个很大的谓词集合(~1000个谓词),用于过滤匹配这些谓词的任何
Person
。例如,谓词可以是

  • person.getName().equals(“丑陋的名字1”)
  • person.getName().equals(“丑陋的名字2”)
  • person.getAge()<18
这一要求带来了以下挑战:

  • 过滤速度要快
  • 谓词是“业务定义”的,因此应易于添加和删除谓词。这意味着谓词可能不应该在源代码中硬编码,但最好在数据库中维护(?)

这些挑战的解决方案是什么?有什么库可以提供帮助吗?

我建议您按照执行速度的顺序对谓词进行排序。然后,您可以按照速度的顺序执行谓词,首先使用最快的谓词,这通常意味着较慢的谓词必须在较小的集合上运行

然而,这个假设并不完全正确,您需要计算删除谓词的百分比以提高执行速度。然后我们可以看到哪个谓词删除的对象百分比最高,速度最快。然后,我们可以按照这个顺序执行谓词,以获得最佳效果

您可以轻松实现自己的谓词
接口

public interface Predicate<T> {

    boolean filter(T object);

}
公共接口谓词{
布尔滤波器(T对象);
}
然后需要为每个规则创建谓词对象。您可以为年龄和姓名检查创建一些更具动态性的类,这将减少您还需要的代码量

public class AgeCheck<T> implements Predicate<T> {

    private final int min;
    private final int max;
    public AgeCheck(int min, int max) {
        this.min = min;
        this.max = max;
    }

    @Override
    public boolean filter(T object) {
        // if( t.age() < max && t.age > min) ...
    }

}
public类AgeCheck实现谓词{
私人最终整数分钟;
私人最终整数最大值;
公共年龄检查(最小整数、最大整数){
this.min=min;
this.max=max;
}
@凌驾
公共布尔过滤器(T对象){
//如果(t.age()min)。。。
}
}

在这种情况下,相对于操作本身的复杂性,您可以做的不多。如果条目多,谓词多,谓词昂贵,那么您可以尽可能快地进行优化,但您肯定不会超过某个阈值,因为这里的单个操作可能昂贵

您应该测试不同的方法,看看什么方法在您的具体情况下表现更好:

  • 通过首先检查应该更宽的谓词来对谓词进行排序(以便第一个谓词将筛选出尽可能多的条目)
  • 根据谓词的复杂程度对其进行排序(以便先执行更快的谓词,然后对更少的条目执行较慢的谓词)
  • 不更新原始数据结构,但保留一个并行集,其中将包含过滤后的元素
  • 始终更新数据结构,以便每次循环的人数较少

    • 这里有一个替代方案:识别类实例可能具有的所有可能属性。在您的示例中,您有一个具有两个属性的
      person
      类;姓名和年龄。因为您有这些属性的getter,所以一个
      人最多可能有两个属性(除非您没有提到其他getter)。您可以实现
      person
      ,这样属性就保存在一个集合中,这样您就可以真正不限制属性的数量。无论它是如何实现的,都要识别所有属性

      现在,对于每个属性,关联一个唯一的素数,然后对于
      person
      的每个实例,维护与分配给该
      person
      的那些属性对应的素数的乘积。例如,假设一个人可以是年轻人或老年人、男性或女性、长得好看或不好看。这是6个属性,让我们按如下方式分配素数:

      02: young
      03: old
      05: male
      07: female
      11: good looking
      13: bad looking
      
      继续这个例子,假设一个人是一个漂亮的年轻女性。素数的乘积是2x7x11,或154

      现在你想找到所有漂亮的年轻人,不管性别。与这个谓词相关的素数的乘积是2x11,或22

      因此,您现在可以遍历所有
      人员
      ,如果与每个
      人员
      相关联的素数的乘积可以被22除,而没有任何余数(在
      人员
      与素数的乘积为154的情况下可以),则您有一个匹配项

      您可能希望使用BigNumber类来执行素数乘积的乘法、除法和存储

      如果给您一个
      person
      ,并询问它是否匹配所有谓词(同样,谓词已缩减为唯一素数,谓词集合现在由这些素数的乘积表示),则此解决方案非常快速

      如果你必须迭代整个
      人的集合来寻找匹配项,那么这个解决方案可能不会这么快。

      (我还没意识到这个问题已经2岁了。我参加这个聚会太晚了!最好知道作者最终使用了什么解决方案。)

      这里有图书馆可以帮忙吗?当然有

      您的数据收集不是很大,但谓词的数量不成比例。另外,您希望这些谓词由您的用户管理,并集中存储等。这听起来很适合,因为它是一个规则引擎,并附带了编写、验证和存储此类规则的附加工具

      但是流口水的人可能会很多,而且也会涉及其中。也许你需要更简单的?你的代码样本,以及你对速度的第一个要求,让我