sti*_*ian 29 java sql collections
假设您有几百个内存中对象的集合,并且您需要查询此List以返回与某些SQL或条件(如查询)匹配的对象.例如,您可能拥有一个汽车列表对象,并且您想要返回在20世纪60年代制造的所有汽车,车牌以AZ开头,按车型名称排序.
我知道JoSQL,有没有人使用过这个,或者有其他/本土解决方案的经验?
npg*_*all 25
过滤是实现此目的的一种方式,如其他答案中所述.
但是过滤不可扩展.从表面上看,时间复杂度似乎是O(n)(即,如果集合中的对象数量增长,则已经不可扩展),但实际上是因为需要根据查询,时间对每个对象应用一个或多个测试复杂度更准确的是O(nt),其中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'}}
Run Code Online (Sandbox Code Playgroud)
然后给出查询WHERE Car.color = 'blue'
,可以在O(1)时间复杂度中检索该组蓝色汽车.如果您的查询中还有其他测试,则可以测试该候选集中的每辆汽车,以检查它是否与查询中的其余测试相匹配.由于候选集可能明显小于整个集合,因此时间复杂度小于 O(n)(在工程意义上,请参见下面的评论).将其他对象添加到集合时,性能不会降低太多.但这仍然不完美,请继续阅读.
另一种方法是我将其称为常设查询索引.为了解释:使用传统的迭代和过滤,迭代集合并测试每个对象以查看它是否与查询匹配.因此,过滤就像在集合上运行查询一样.一个常设查询索引将是另一种方式,其中集合反而在查询上运行,但对于集合中的每个对象只运行一次,即使可以多次查询该集合.
一个站在查询索引会像某种注册查询智能集合,使得当对象被加入,并移除了,那么这个集合将自动检测每个对象对所有已注册与它的地位查询.如果对象与常设查询匹配,则该集合可以向/从专用于存储与该查询匹配的对象的集合添加/移除它.随后,可以以O(1)时间复杂度检索与任何已注册查询匹配的对象.
以上信息来自CQEngine(Collection Query Engine).这基本上是一个NoSQL查询引擎,用于使用类似SQL的查询从Java集合中检索对象,而无需迭代集合.它围绕上面的想法,再加上一些.免责声明:我是作者.它是开源的,在maven中心.如果您觉得它有用,请upvote这个答案!
是的,我知道这是一个老帖子,但技术每天都会出现,答案会随着时间的推移而改变.
我认为使用LambdaJ解决它是一个很好的问题.您可以在此处找到它:http: //code.google.com/p/lambdaj/
这里有一个例子:
寻找活跃的客户//(可转换的版本)
List<Customer> activeCustomers = new ArrayList<Customer>();
for (Customer customer : customers) {
if (customer.isActive()) {
activeCusomers.add(customer);
}
}
Run Code Online (Sandbox Code Playgroud)
LambdaJ版本
List<Customer> activeCustomers = select(customers,
having(on(Customer.class).isActive()));
Run Code Online (Sandbox Code Playgroud)
当然,拥有这种美感会影响性能(有点......平均2次),但是你能找到更易读的代码吗?
它有许多功能,另一个例子可能是排序:
排序迭代
List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
}
});
Run Code Online (Sandbox Code Playgroud)
用lambda排序
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
31538 次 |
最近记录: |