【问题标题】:Convert a List of Object to Map<String,String> using jdk 8 lambdas使用 jdk 8 lambda 将对象列表转换为 Map<String,String>
【发布时间】:2017-12-08 19:23:39
【问题描述】:

我想使用 jdk 8 lambdas 将 List&lt;Properies&gt; 转换为 Map&lt;String,String&gt; 而不执行 for 循环。该地图应包含作为 SubProperty.name 的键和作为 Properties.value 的值。

public class Properties
{
    private SubProperty subProperty;

    private String value;

    public SubProperty getSubProperty()
    {
        return subProperty;
    }

    public void setSubProperty(SubProperty subProperty)
    {
        this.subProperty = subProperty;
    }

    public String getValue()
    {
        return value;
    }

    public void setValue(String value)
    {
        this.value = value;
    }
}

public class SubProperty
{
    private String category;
    private String name;

    public String getCategory()
    {
        return category;
    }

    public void setCategory(String category)
    {
        this.category = category;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
}

【问题讨论】:

标签: java lambda java-8


【解决方案1】:

类似这样的:

List<Properties> properties = ...
Map<String, String> map = properties.stream()
    .collect(Collectors.toMap(prop -> prop.getSubProperty().getName(), prop -> prop.getValue()));

【讨论】:

    【解决方案2】:

    当您使用Collectors.toMap()Stream 构造Map 时,您必须考虑您的Stream 是否可能包含重复的键。在您的情况下,重复键意味着多个 Properties 实例具有相同名称的 SubProperty

    要解决重复问题,您可以使用 Collectors.toMap 的 3 个参数变体。例如下面遇到重复键时会选择getValue()值之一:

    Map<String,String> map = 
        list.stream()
            .collect(Collectors.toMap(p -> p.getSubProperty().getName(),
                                      Properties::getValue,
                                      (v1,v2) -> v1));
    

    另一种选择是使用Collectors.groupingBy,它将共享相同键的值分组到List

    Map<String,List<String>> map = 
        list.stream()
            .collect(Collectors.groupingBy(p -> p.getSubProperty().getName(),
                                           Collectors.mapping(Properties::getValue,
                                                              Collectors.toList())));
    

    【讨论】:

    • 如果尝试存储 Map 中已存在的键,则由 Collectors.toMap 创建的收集器会抛出 IllegalStateException。如果您想在 Map 中收集项目并且希望源中有重复条目,则应使用 Collectors.toMap(Function, Function, BinaryOperator) 方法。这是正确而完整的答案。
    • @AlexMamo 除非你知道你不会有重复,如果你会想要那个例外......
    猜你喜欢
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    相关资源
    最近更新 更多