Как искать элемент в списке? - PullRequest
1 голос
/ 23 апреля 2019

У меня есть два списка, например:

Список 1: имеет только один элемент

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

Список 2: имеет 1000 объектов

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

a.matIDS

Примечание: matIDSis String collection (например: 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:

В списке 1 есть только 1 элемент, где в списке 2 есть 1000. Нужно ли мнепроверить все эти 1000, чтобы найти 1 элемент?

Есть ли лучший способ?

Ответы [ 3 ]

1 голос
/ 23 апреля 2019

Вы можете оптимизировать существующий код для выхода из циклов, когда совпадение найдено.

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

Надеюсь, это поможет.

0 голосов
/ 23 апреля 2019

Если под «лучше» вы подразумеваете более четкое, то, возможно, вы могли бы рассмотреть возможность использования потоков:

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

Считаете ли вы это «лучше», зависит от того, что вы хотите.

Если вырегулярно проверяем, есть ли конкретный идентификатор в списке, вы можете собрать идентификаторы в наборе:

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

Затем проверка, находится ли конкретная строка в наборе, тривиальна, не возвращаясь к оригиналусписок.

0 голосов
/ 23 апреля 2019

Если вам действительно нужно быстро найти значение (или значения) в одном списке относительно другой коллекции, то, возможно, самой быстрой структурой данных для этого будет поиск по набору:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...