Java-在3个集合上匹配条件以更新其中1个集合

Java-在3个集合上匹配条件以更新其中1个集合,java,collections,java-stream,Java,Collections,Java Stream,考虑类Site、Tag和SiteTagRelation。我收集了每一个。对于每个站点,我需要通过在关系类中查找找到所有相应的标记,然后将匹配的标记添加到站点对象 它可以通过循环完成,但既不优雅也不高效。我想找到一个具有流的单行程序解决方案,但我无法理解如何使3个集合在同一表达式中共存。任何关于如何实现这一点的提示都是受欢迎的 public class Tag { private int id; ... } public class Site { private int id;

考虑类Site、Tag和SiteTagRelation。我收集了每一个。对于每个站点,我需要通过在关系类中查找找到所有相应的标记,然后将匹配的标记添加到站点对象

它可以通过循环完成,但既不优雅也不高效。我想找到一个具有流的单行程序解决方案,但我无法理解如何使3个集合在同一表达式中共存。任何关于如何实现这一点的提示都是受欢迎的

public class Tag {
   private int id;
...
}

public class Site {
   private int id;
   Collection<Tag> tags;
...
}

public class SiteTagRelation {
   private int siteId;
   private int tagId;
...
}

public static void main(String[] arg) {
   Collection<SiteTagRelation> tagMapping = ...
   Collection<Site> sites = ...
   Collection<Tag> tags = ...

   // The expression I am struggling with should be here
   // From that point, all sites with a tag in sites should have a non-empty tags collection within itself
}
公共类标记{
私有int-id;
...
}
公共类网站{
私有int-id;
收集标签;
...
}
公共类站点关系{
私有int站点ID;
私有int-tagId;
...
}
公共静态void main(字符串[]arg){
集合标记映射=。。。
收集网站=。。。
集合标记=。。。
//我正在挣扎的表达应该在这里
//从这一点来看,在sites中具有标记的所有站点本身都应该有一个非空标记集合
}
我的循环解法

private void enrichSite(Collection<Site> sites) {

        for(Site site : sites) {

            // Get all the matching relation
            Set<SiteTagRelation> matchingTagRelation = tagMapping.stream().filter(x -> x.getSiteId().equals(site.getId())).collect(Collectors.toSet());

            Set<Tag> matchingTags = new HashSet<Tag>();

            // Add each tag found to the collection
            for(SiteTagRelation mapping : matchingTagRelation) {
                Tag foundTag = this.tags().stream().filter(x -> x.getId().equals(mapping.getTagId())).findFirst().get();
                matchingTags.add(foundTag);
            }

            // Set the tags on the entity
            site.setTags(matchingTags);

        }
    }
private void enrichSite(收集站点){
用于(站点:站点){
//获取所有匹配关系
设置matchingTagRelation=tagMapping.stream().filter(x->x.getSiteId().equals(site.getId()).collect(Collectors.toSet());
Set matchingTags=new HashSet();
//将找到的每个标记添加到集合中
对于(SiteTagRelationship映射:MatchingTagRelationship){
Tag foundTag=this.tags().stream().filter(x->x.getId().equals(mapping.getTagId()).findFirst().get();
匹配标签。添加(foundTag);
}
//在实体上设置标记
站点。设置标签(匹配标签);
}
}

流的
解决方案如下所示,这是一种冗长的解决方案,但它与循环相同,为了清晰起见,这里应该首选循环

private void enrichSite(Collection<Site> sites) {
    sites.forEach(site ->
        site.setTags(tagMapping.stream().filter(x -> x.getSiteId().equals(site.getId()))
            .map(mapping -> this.tags.stream().filter(x -> x.getId().equals(mapping.getTagId())).findFirst().get())
            .collect(Collectors.toSet())));
}

“可以通过循环实现”至少,向我们展示您基于循环的解决方案。可以通过循环实现,但它既不优雅也不高效。。。你为什么这么认为?@Michael:我已经更新了帖子。我的错误。你知道怎么做吗?@Naman:我怀疑流API扫描集合的方式会比我在
int
上的循环
equals
更好。我将玩弄您的实现,并决定是保留它还是返回循环
class Tag {
    private int id;
    // ...
    static Tag useless() {
        return new Tag(-1);
    }
}


private void enrichSite(Collection<Site> sites) {
    sites.forEach(site ->
        site.setTags(tagMapping.stream().filter(x -> x.getSiteId().equals(site.getId()))
            .map(mapping -> this.tags.stream().filter(x -> x.getId().equals(mapping.getTagId())).findFirst().orElseGet(Tag::useless))
            .filter(tag -> tag.getId() != -1)
            .collect(Collectors.toSet())));
}