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