简体   繁体   English

检查列表是否包含 java 中另一个列表的任何项目

[英]Check if list contains any item of another list in java

We have two lists one is of type Question and the other of type Tag .我们有两个列表,一个是Question类型,另一个是Tag类型。

The Question class has those attributes问题 class 具有这些属性

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

The Question list has several questions in it and the Tag list has all tags in it.问题列表中有几个问题,标签列表中有所有标签。 We wanna check if One question contains any tag of the tag list.我们想检查一个问题是否包含标签列表的任何标签。 I want to do this for all questions.我想对所有问题都这样做。

With question.getTags , I get the list of tags.使用question.getTags ,我得到标签列表。

I tried我试过了

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
        }
    }
}

This is not quite doing what I want to do, I think I have to do something with streams but I could not quite figure out how I exactly have to write the code.这并不是我想做的事情,我想我必须对流做一些事情,但我不太清楚我究竟是如何编写代码的。

You're performing the operation for every tag that's in the list instead of once per question if any tag is in the list.如果列表中有任何标签,您正在为列表中的每个标签执行操作,而不是每个问题一次。

As you proposed, using streams could make this solution easier:正如您所建议的,使用流可以使这个解决方案更容易:

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

Note - this still has an O(m * n) runtime complexity, where m is the number of questions and n is the number of tags.注意 - 这仍然具有 O(m * n) 运行时复杂度,其中 m 是问题的数量,n 是标签的数量。 You can optimize this to an O(m + n) runtime complexity by creating a Set from the list of tags so that the contains operation has an O(1) time complexity.您可以通过从标签列表创建一个Set其优化为 O(m + n) 运行时复杂度,以便contains操作具有 O(1) 时间复杂度。

Try:尝试:

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

Or are you asking whether the a given question contains a token from the question.tags() list?或者您是在询问给定问题是否包含 question.tags() 列表中的标记?

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
    }
}

To get all tags that contain in alltags list and their occurrence map获取所有标签列表中包含的所有标签及其出现alltags

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

Then you can add this list in another list if you want.然后,您可以根据需要将此列表添加到另一个列表中。 And recomend you to make a set for alltags then it will faster since allTagsSet.contains takes O(1) only.并建议您为alltags设置一个集合,然后它会更快,因为allTagsSet.contains需要O(1)

Apache commons have an utility method for that: CollectionUtils#containsAny Apache commons 有一个实用方法: CollectionUtils#containsAny

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

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