简体   繁体   English

如何搜索列表中的元素?

[英]How to search element in a List?

I have two lists for eg :我有两个列表,例如:

List 1 : has only one element列表 1:只有一个元素

List<String> ids=new ArrayList<String>();

List 2 : has 1000 objects列表 2:有 1000 个对象

List<ABC> abc=  new ArrayList<ABC>();

a.matIDS

Note: matIDS is String collection (for eg : abc,def,ghi)注意: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:::");
        }
    }
}

question:题:

In list 1 there is only 1 element where as in list 2 there are 1000. Do i need to check all those 1000 to find the 1 element?在列表 1 中只有 1 个元素,而在列表 2 中有 1000 个元素。我是否需要检查所有这些 1000 个元素才能找到第 1 个元素?

Is there any better way?有没有更好的办法?

If you really need to rapidly lookup a value (or values) in one list against another collection, then perhaps the fastest data structure for this would be to search against a set:如果您确实需要针对另一个集合快速查找一个列表中的一个(或多个)值,那么最快的数据结构可能是针对一组进行搜索:

Set<String> set = new HashSet<>(abc);

Then, you may iterate the first list and lookup each entry in constant time in the other collection:然后,您可以迭代第一个列表并在另一个集合中以恒定时间查找每个条目:

for (String id : ids) {
    if (set.contains(id)) {
        LOG.info("ID found:::");
    }
    else {
        LOG.info("ID NOT found:::");
    }
}

This is an improvement over your current brute force approach, which was O(n*m) , where n and m are the sizes of the ids and abc lists.这是对您当前的蛮力方法的改进,即O(n*m) ,其中nmidsabc列表的大小。 Now, the running time is just O(m) , the size of the ids list.现在,运行时间只是O(m) ,即ids列表的大小。

If by 'better' you mean clearer then perhaps you might consider using streams:如果“更好”的意思更清楚,那么也许您可以考虑使用流:

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

Whether you consider this 'better' depends on what you are after.您是否认为这“更好”取决于您的追求。

If you are regularly checking whether a particular ID is in the list then you could collect the IDs in a set:如果您定期检查特定 ID 是否在列表中,那么您可以收集一组 ID:

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

Then checking if a particular string is in the set is trivial without having to go back to the original list.然后检查特定字符串是否在集合中是微不足道的,而不必返回原始列表。

You can optimize your existing code to exit the loops when match found.您可以优化现有代码以在找到匹配项时退出循环。

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:::");

You may also use streams,你也可以使用流,

boolean isFound=abc.stream().flatMap(e-> e.matIDS.stream()).anyMatch(ids::contains);
if(isFound)
    LOG.info("ID found:::");
else
    LOG.info("ID NOT found:::");

To find which elements matched, you can use filter and collect in a Set要查找匹配的元素,您可以使用filter并在Set收集

  Set<String>  matchedElements=abc.stream()
                .flatMap(e-> e.matIDS.stream())
                .filter(ids::contains)
                .collect(Collectors.toSet());

Hope it helps.希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM