我有两个列表,例如:
清单1:只有一个元素
List<String> ids=new ArrayList<String>();
清单2:有1000个对象
List<ABC> abc= new ArrayList<ABC>();
a.matIDS
注意:matIDS是字符串集合(例如:abc,def,ghi)
for(ABC a : abc){
for(String id : a.matIDs()){
if(ids.contains(id)){
LOG.info("ID found:::");
}else{
LOG.info("ID NOT found:::");
}
}
}
问题:
列表1中只有1个元素,而列表2中只有1000个元素。 我是否需要检查所有这1000个元素才能找到1个元素?
还有更好的方法吗?
答案 0 :(得分:1)
您可以优化现有代码以在找到匹配项时退出循环。
booean isFound=false;
for(ABC a : abc){
for(String id : a.matIDs()){
if(ids.contains(id)){
isFound=true;
break;
}
}
if(isFound)
break;
}
if(isFound)
LOG.info("ID found:::");
else
LOG.info("ID NOT found:::");
您还可以使用流,
boolean isFound=abc.stream().flatMap(e-> e.matIDS.stream()).anyMatch(ids::contains);
if(isFound)
LOG.info("ID found:::");
else
LOG.info("ID NOT found:::");
要查找匹配的元素,可以使用filter
并收集到Set
Set<String> matchedElements=abc.stream()
.flatMap(e-> e.matIDS.stream())
.filter(ids::contains)
.collect(Collectors.toSet());
希望有帮助。
答案 1 :(得分:0)
如果您确实确实需要针对另一个集合快速在一个列表中查找一个或多个值,那么最快的数据结构可能就是针对某个集合进行搜索:
Set<String> set = new HashSet<>(abc);
然后,您可以迭代第一个列表,并在恒定时间内在另一个集合中查找每个条目:
for (String id : ids) {
if (set.contains(id)) {
LOG.info("ID found:::");
}
else {
LOG.info("ID NOT found:::");
}
}
这是对您当前的O(n*m)
暴力破解方法的改进,其中n
和m
的大小是ids
和abc
列表。现在,运行时间仅为O(m)
,即ids
列表的大小。
答案 2 :(得分:0)
如果“更好”意味着您更清晰,那么也许您可以考虑使用流:
abc.stream().flatMap(ABC::matIDs).anyMatch(ids::contains);
您是否认为“更好”取决于您的追求。
如果您定期检查列表中是否有特定的ID,则可以将ID集中收集:
Set<String> abcIDs = abc.stream().flatMap(ABC::matIDs).collect(toSet());
然后检查特定字符串是否在集合中是微不足道的,而不必返回原始列表。