【问题标题】:map from string to multiple different strings and add to list with Java stream从字符串映射到多个不同的字符串并使用 Java 流添加到列表
【发布时间】:2024-04-17 06:55:02
【问题描述】:

我是 Java 8 和 Streams 的新手。 我有一个 PolicyDefinition 对象,它有两个方法:getAlias,getName,它们都返回一个字符串。 有没有一种优雅的方法可以在一个语句中使用 Stream(从 PolicyDefinition 集合创建)创建一个包含所有别名和策略定义名称的列表?

有两个陈述不是问题:

List<String> policyNames = 
              policyDefinitions.stream()
                               .map(definition -> definition.getName())
                               .collect(Collectors.toList());

List<String> policyAlias = 
              policyDefinitions.stream()
                               .map(definition -> definition.getAlias())
                               .collect(Collectors.toList());

但有可能合二为一吗?

非常感谢您的帮助

【问题讨论】:

    标签: java-8 java-stream


    【解决方案1】:

    flatMap它!

    List<String> policyNames = policyDefinitions.stream()
        .flatMap(definition -> Stream.of(definition.getName(), definition.getAlias()))
        .collect(Collectors.toList());
    

    正如the comments 中提到的——为了整洁,在Definition 中创建一个方法

    public Stream<String> allNames() {
        return Stream.of(getName(), getAlias())
    }
    

    然后

    List<String> policyNames = policyDefinitions.stream()
        .flatMap(Definition::allNames)
        .collect(Collectors.toList());
    

    OP comments "我忘了说getAlias 可能是null,你会做什么呢[原文如此]"

    在这种情况下,请使用Optional

    public Stream<String> allNames() {
        return Stream.concat(Stream.of(getName()), Optional.ofNullable(getAlias()).stream())
    }
    

    【讨论】:

    • 我忘了说 getAlias 可能会返回 null,你会做什么呢?
    • 请注意,从 JDK9 开始,可选只有 stream 方法,JDK8 的替代方法可能是创建自己的方法来执行此类操作或过滤掉空值,如 List&lt;String&gt; policyNames = policyDefinitions.stream() .flatMap(Definition::allNames).filter(Objects::nonNull) .collect(Collectors.toList());
    • @Aominè 好点 Optional.map(Stream::of).orElseGet(Stream::empty) 是我的最爱。
    • 或者干脆Stream.of(getName(), getAlias()).filter(Objects::nonNull)
    【解决方案2】:

    您还可以使用 groupingBuy 运算符创建以别名为键、名称为值的地图

    【讨论】:

      最近更新 更多