0

我有两个列表,例如:

清单 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 个元素?

有没有更好的办法?

4

3 回答 3

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), wherenmare theidsabc列表的大小。现在,运行时间只是列表O(m)的大小ids

于 2019-04-23T05:12:07.460 回答
0

如果“更好”的意思是更清晰,那么也许您可以考虑使用流:

abc.stream().flatMap(ABC::matIDs).anyMatch(ids::contains);

您是否认为这“更好”取决于您所追求的。

如果您定期检查特定 ID 是否在列表中,那么您可以收集一组 ID:

Set<String> abcIDs = abc.stream().flatMap(ABC::matIDs).collect(toSet());

然后检查特定字符串是否在集合中是微不足道的,而无需返回原始列表。

于 2019-04-23T06:23:42.400 回答
0

您可以优化现有代码以在找到匹配项时退出循环。

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());

希望能帮助到你。

于 2019-04-23T07:10:53.200 回答