模型:
public class AgencyMapping {
private Integer agencyId;
private String scoreKey;
}
public class AgencyInfo {
private Integer agencyId;
private Set<String> scoreKeys;
}
我的代码:
List<AgencyMapping> agencyMappings;
Map<Integer, AgencyInfo> agencyInfoByAgencyId = agencyMappings.stream()
.collect(groupingBy(AgencyMapping::getAgencyId,
collectingAndThen(toSet(), e -> e.stream().map(AgencyMapping::getScoreKey).collect(toSet()))))
.entrySet().stream().map(e -> new AgencyInfo(e.getKey(), e.getValue()))
.collect(Collectors.toMap(AgencyInfo::getAgencyId, identity()));
有没有办法获得相同的结果并使用更简单和更快的代码?
最佳答案
您可以简化对 collectingAndThen(toSet(), e -> e.stream().map(AgencyMapping::getScoreKey).collect(toSet()))))
的调用。调用mapping(AgencyMapping::getScoreKey, toSet())
.
Map<Integer, AgencyInfo> resultSet = agencyMappings.stream()
.collect(groupingBy(AgencyMapping::getAgencyId,
mapping(AgencyMapping::getScoreKey, toSet())))
.entrySet()
.stream()
.map(e -> new AgencyInfo(e.getKey(), e.getValue()))
.collect(toMap(AgencyInfo::getAgencyId, identity()));
使用
toMap
的另一种查看方式集电极:Map<Integer, AgencyInfo> resultSet = agencyMappings.stream()
.collect(toMap(AgencyMapping::getAgencyId, // key extractor
e -> new HashSet<>(singleton(e.getScoreKey())), // value extractor
(left, right) -> { // a merge function, used to resolve collisions between values associated with the same key
left.addAll(right);
return left;
}))
.entrySet()
.stream()
.map(e -> new AgencyInfo(e.getKey(), e.getValue()))
.collect(toMap(AgencyInfo::getAgencyId, identity()));
后一个例子可以说比前一个更复杂。尽管如此,您的方法几乎是与使用
mapping
不同的方法。而不是 collectingAndThen
正如刚才提到的。除此之外,我看不到您可以使用显示的代码简化的任何其他内容。
至于更快的代码,如果您建议您当前的方法性能较慢,那么您可能需要阅读答案 here谈到何时应该考虑并行。
关于performance - 使用 java 8 流将键值对转换为按键对象映射分组的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49476787/