使用java 8流将键值对转换为按键对象映射的最快方法

Jac*_*ack 6 collections performance java-8 java-stream

模型:

public class AgencyMapping {
    private Integer agencyId;
    private String scoreKey;
}

public class AgencyInfo {
    private Integer agencyId;
    private Set<String> scoreKeys;
}
Run Code Online (Sandbox Code Playgroud)

我的代码:

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()));
Run Code Online (Sandbox Code Playgroud)

有没有办法获得相同的结果,使用更简单的代码,更快?

Ous*_* D. 4

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()));
Run Code Online (Sandbox Code Playgroud)

使用收集器查看它的另一种方式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()));
Run Code Online (Sandbox Code Playgroud)

后一个例子可以说比前一个例子更复杂。然而,您的方法几乎是与使用相反的方法mapping而不是collectingAndThen上面提到的方法。

除此之外,我看不出您可以使用所示代码来简化任何其他内容。

至于更快的代码,如果您认为当前的方法性能缓慢,那么您可能需要阅读此处的答案,其中谈到何时应该考虑并行。