假设您有一个包含数百个内存对象的集合,并且您需要查询此 List 以返回与某些 SQL 或 Criteria 类查询匹配的对象。例如,您可能有一个 Car 对象列表,并且您希望返回 1960 年代制造的所有汽车,车牌以 AZ 开头,按车型名称排序。
我知道 JoSQL ,有没有人使用过这个,或者对其他/本土解决方案有任何经验?
最佳答案
过滤是执行此操作的一种方法,如其他答案中所述。
过滤是不可扩展的。从表面上看,时间复杂度似乎是 O(n)(即,如果集合中的对象数量会增加,则已经无法扩展),但实际上是因为一个 或多个需要根据查询对每个对象应用测试,更准确的时间复杂度是 O(n t),其中 t 是应用到每个对象的测试数。
所以性能会随着额外的对象添加到集合中而降低,和/或随着查询中测试数量的增加。
还有另一种方法可以做到这一点,使用索引和集合论。
一种方法是在您的集合中存储的对象内的字段上构建索引,然后您将在查询中对其进行测试。
假设您有一个 Car
对象的集合,并且每个 Car
对象都有一个字段 color
。假设您的查询相当于“SELECT * FROM cars WHERE Car.color = 'blue'
”。你可以在 Car.color
上建立一个索引,它基本上看起来像这样:
'blue' -> {Car{name=blue_car_1, color='blue'}, Car{name=blue_car_2, color='blue'}}
'red' -> {Car{name=red_car_1, color='red'}, Car{name=red_car_2, color='red'}}
然后给定一个查询 WHERE Car.color = 'blue'
,可以在 O(1) 时间复杂度内检索蓝色汽车的集合。如果您的查询中有其他测试,您可以测试该候选集中的每辆车,以检查它是否与查询中的其余测试相匹配。由于候选集可能远小于整个集合,因此时间复杂度小于 O(n)(在工程意义上,请参见下面的评论)。将其他对象添加到集合中时,性能不会降低那么多。但这仍然不完美,请继续阅读。
另一种方法,我称之为常设查询索引。解释一下:通过传统的迭代和过滤,对集合进行迭代并测试每个对象以查看它是否与查询匹配。所以过滤就像在一个集合上运行一个查询。常设查询索引则相反,集合会在查询上运行,但对于集合中的每个对象仅运行一次,即使该集合可以被查询任意次数。
常设查询索引就像用某种智能集合注册查询,这样当对象被添加到集合中或从集合中移除时,集合将根据已注册的所有常设查询自动测试每个对象。如果对象与常设查询匹配,则集合可以将其添加到/从专用于存储与该查询匹配的对象的集合中删除。随后,可以在 O(1) 时间复杂度内检索匹配任何已注册查询的对象。
以上信息取自CQEngine (Collection Query Engine) .这基本上是一个 NoSQL 查询引擎,用于使用类似 SQL 的查询从 Java 集合中检索对象,而无需遍历集合的开销。它是围绕上述想法构建的,还有更多。免责声明:我是作者。它是开源的,位于 Maven 中心。 如果你觉得有帮助,请点赞这个答案!
关于java - 如何在 Java 中查询对象集合(Criteria/SQL-like)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/93417/