我有2个ArrayLists,它们有一个字符串数组作为“组件”。我想找到两个ArrayLists中第一个元素相同的“components”。 更清楚:
ArrayList One
first component => {"0", "zero"}
second component => {"1", "one"}
ArrayList Two
first component => {"1", "uno"}
second component => {"2", "two"}
我想遍历ArrayList Two并找到{“1”,“uno”}。 到目前为止,我有一个嵌套循环,循环遍历第一个数组,然后检查当前组件到ArrayList Two中的每个组件。
for(int i=0; i<One.size(); i++)
{
for(int j=0; j<Two.size(); j++)
{
if( fileOne.get(i)[0].equals( Two.get(j)[0] ) )
{
System.out.print( Two.get(j)[0]+" " );
System.out.print( Two.get(j)[1] );
System.out.println();
}
}
}
我认为应该有更好的解决方案。任何帮助
答案 0 :(得分:2)
您可以尝试使用hashmap。通过将每个组件的第一个元素映射到组件(或组件的索引),从第一个ArrayList初始化它。然后,对于第二个ArrayList的每个组件,您可以通过每个组件的第一个元素查找匹配组件(或者在返回null
时发现没有组件)。
答案 1 :(得分:2)
使用HashSet。
Set<String> set = new HashSet<String>()
for(int i=0; i<One.size(); i++) {
set.add(fileOne.get(i)[0]);
}
for(int i=0; i<Two.size(); i++) {
String component[] = Two.get(j)
if(set.contains(component[0])) {
System.out.print( component[0]+" " );
System.out.print( component[1] );
System.out.println();
}
}
注意:列表在这种情况下不起作用,因为列表中的查找是O(N)。 HashSets中的查找是O(1),因此构建集合(第一个循环)是O(N)。然后通过你的第二个数组是O(M),每个查找是O(1)。
总的来说,这变成O(N)+(O(M)* O(1))= O(N + M)
编辑:对于特德的评论。
答案 2 :(得分:1)
One.retainAll(Two)
复杂性明智更好 - 只有O(n + m)对你的O(n * m)。而且在可读性和可维护性方面也更好。请注意,如果您不希望行为生成第三个副本,retainAll
将修改散列集One
。
答案 3 :(得分:-1)
(根据特德的评论编辑)
如果没有初始化工作,例如排序/散列,或维护已排序/散列列表,没有更好的解决方案,最佳解决方案是你的O(n * m)。这是最佳解决方案,因为您必须将每个元素与每个其他元素进行比较。
我还应该提到,在某些情况下,保持列表排序可能更明智。然后,不是比较每个元素,你可以使用二进制搜索或其他东西。但是如果没有先排序列表,是的,你必须比较所有元素。我相信最好的分拣时间是O(nlgn)。然后在排序过程之后,您仍然需要搜索元素的排序列表,但搜索排序列表可能比搜索未排序列表更快。