首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 8 List<T> V> Map<K,V>

Java 8 List<T> V> Map<K,V>
EN

Stack Overflow用户
提问于 2014-09-25 22:28:19
回答 2查看 2.2K关注 0票数 5

我希望将对象列表转换为Map,其中Map的键和值作为列表中的对象内部的属性。

这里是这种转换的Java 7片段:

代码语言:javascript
复制
private Map<String, Child> getChildren(List<Family> families  ) {
        Map<String, Child> convertedMap = new HashMap<String, Child>();

        for (Family family : families) {
            convertedMap.put(family.getId(), family.getParent().getChild());
        }
        return convertedMap;
    }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-25 22:46:25

应该类似于..。

代码语言:javascript
复制
Map<String, Child> m = families.stream()
    .collect(Collectors.toMap(Family::getId, f -> f.getParent().getChild()));
票数 11
EN

Stack Overflow用户

发布于 2014-09-26 04:15:13

Jason给出了一个decent answer (+1),但我应该指出,它的语义与OP的Java 7代码不同。如果输入列表中的两个家族实例具有重复的ID,则该问题涉及行为。也许他们被保证是独一无二的,在这种情况下没有区别。但是,如果使用OP的原始代码存在重复,列表后面的Family将覆盖具有相同ID的列表前面的Family的映射条目。

使用Jason的代码(如下所示,稍加修改):

代码语言:javascript
复制
Map<String, Child> getChildren(List<Family> families) {
    return families.stream()
        .collect(Collectors.toMap(Family::getId, f -> f.getParent().getChild()));
}

如果有任何重复的键,Collectors.toMap操作将抛出IllegalStateException。这有点令人不快,但至少它会通知您存在重复的数据,而不是潜在地丢失数据。Collectors.toMap(keyMapper, valueMapper)的规则是,您需要确保键映射函数为流的每个元素返回一个唯一的键。

你需要做些什么--如果有的话--取决于问题域。一种可能是使用三arg版本:Collectors.toMap(keyMapper, valueMapper, mergeFunction)。这指定了在重复情况下调用的额外函数。如果希望后面的条目覆盖以前的条目(与原始的Java 7代码匹配),可以这样做:

代码语言:javascript
复制
Map<String, Child> getChildren(List<Family> families) {
    return families.stream()
        .collect(Collectors.toMap(Family::getId, f -> f.getParent().getChild(),
                                                 (child1, child2) -> child2));
}

另一种选择是为每个家庭建立一份子女清单,而不是只生一个孩子。您可以编写一个更复杂的合并函数,该函数为第一个子表创建一个列表,并为第二个和随后的子程序追加到此列表中。这是如此常见,以至于有一个特殊的groupingBy收集器可以自动完成此操作。这本身就会产生一个按ID分组的家庭列表。我们不需要一个家庭列表,而是想要一个孩子列表,因此我们添加了一个下游映射操作来从一个家庭映射到另一个孩子,然后将孩子收集到一个列表中。代码将如下所示:

代码语言:javascript
复制
Map<String, List<Child>> getChildren(List<Family> families) {
    return families.stream()
        .collect(Collectors.groupingBy(Family::getId,
                    Collectors.mapping(f -> f.getParent().getChild(),
                        Collectors.toList())));
}

请注意,返回类型已从Map<String, Child>更改为Map<String, List<Child>>

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26049187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档