Проверить, содержит ли список какой-либо элемент другого списка в java - PullRequest
0 голосов
/ 18 июня 2020

У нас есть два списка: один имеет тип Question, а другой - тип Tag.

Класс Question имеет эти атрибуты

private String id;
private String header;
private String content;
private List<Tag> tags;
private Long timeStamp;

Список вопросов содержит несколько вопросов в нем, и в списке тегов есть все теги. Мы хотим проверить, содержит ли один вопрос какой-либо тег из списка тегов. Я хочу сделать это для всех вопросов.

С question.getTags я получаю список тегов.

Я пробовал

List<Question> allQuestions =  ... ; // List of type questions
List<Tags> alltags = ... ;  // List of type tag

for(Question question: allQuestions) {
    for(Tag tag: allTags){
        if(question.getTags().contains(tag)) {
            //do something
        }
    }
}

Это не совсем то, что Я хочу что-то делать, я думаю, что мне нужно что-то делать с потоками, но я не мог понять, как именно мне нужно писать код.

Ответы [ 5 ]

1 голос
/ 18 июня 2020

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

Как вы предложили , использование потоков может упростить это решение:

allQuestions.forEach(question -> {
    if (question.getTags().stream().anyMatch(tag -> allTags.contains(tag)) {
        // do something
    }
});

Примечание - это все еще имеет сложность выполнения O (m * n), где m - количество вопросов, а n - количество тегов. Вы можете оптимизировать это до сложности времени выполнения O (m + n), создав Set из списка тегов, чтобы операция contains имела временную сложность O (1).

0 голосов
/ 18 июня 2020

Чтобы получить все теги, которые содержатся в списке alltags, и карту их вхождения

Map<Tag, Long> map = allQuestions.stream()
                           .flatMap(q -> q.getTags().stream())
                           .filter(t -> allTags.contains(t))
                           .collect(Collectors.groupingBy(e -> e, Collectors.counting()));

Затем вы можете добавить этот список в другой список, если хотите. И рекомендую вам сделать набор для alltags, тогда он будет быстрее, так как allTagsSet.contains принимает только O(1).

0 голосов
/ 18 июня 2020
List<Question> allQuestions =  ... ; // List of type questions
List<Tags> alltags = ... ;  // List of type tag

for (Question x : allQuestions) {
    List<Tag> questionTags = new ArrayList<>();
    questionTags = x.getTags();
    questionTags.retainAll(allTags);
    // questionTags will retain common tags between allTags and x.getTags()            

    for (Tag tag: questionTags) {
        // Execute when there is at least one common tag
    }
}
0 голосов
/ 18 июня 2020

Apache commons имеет для этого служебный метод: CollectionUtils # containsAny

0 голосов
/ 18 июня 2020

Попробуйте:

for(Question question: allQuestions) {
    for(Tag tag: allTags){
        if(question.contains(tag)) {
            //do something
        }
    }
}

Или вы спрашиваете, содержит ли данный вопрос токен из списка question.tags ()?

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