我有list1<String>
和其他1000 list<String>
。我需要选择具有最精确匹配值的列表。
今天我查看每个list<String>
并与list1进行比较,将封面保存在某个排序列表中,最后选择最相似的列表。
public static <T> List<T> intersection(List<T> list1, List<T> list2) {
List<T> list = new ArrayList<T>();
for (T t : list1) {
if(list2.contains(t)) {
list.add(t);
}
}
return list;
}
假设我有很多列表可以比较,那么这个遍历所有1000个唯一列表的操作就会丢失。
请您建议我采用有效的方法/算法吗?
答案 0 :(得分:2)
您的列表未排序,因此任何contains()
操作都需要搜索整个列表(或直到找到N / 2为止)。
首先对所有列表进行排序(Collections.sort()
),然后使用Collections.binarySearch()
查找是否包含String。这只需要(log N)而不是之前的N / 2.
答案 1 :(得分:1)
接受的anwser很好,但仍然可以改进。您可以简单地使用LinkedHashSet
,它将O(n)转储到集合中,并且每个包含操作的O(1)。如果您的列表很大,这将有所帮助,但对于小列表,请使用排序。
如果列表中有重复条目,则可能会产生一些意外结果,因为原始代码会在结果中创建多个条目。在这种情况下,请使用Google Guava&#39; LinkedHashMultiset
之类的内容。如果您没有在类路径上安装Guava,如果您想要O(1)搜索时间,可能需要自己编写一个。
正如旁注,Collections.sort()
将改变原始列表。如果您以后需要原始订单或者列表以某种方式不可修改,您应该创建它的副本,在这种情况下我认为您应该尝试使用该集合,因为它们需要相同的时间来构建,HashSet
使用更少的时间来执行contains