繁体   English   中英

使用 Java 流从 Map 中组装值

[英]Assemble values from Map using Java streams

对不起,也许是愚蠢的问题。 我正在寻找优雅的方式来检查我的地图元素和过滤器属性。

假设我有两个元素的地图。

Map<String, MyElement> myMap;

这就是我的元素的外观

class MyElement {

Map <String, Property1> properties1;
Map <String, Property2> properties2;

}

MyElement[0] 包括用一些属性填充的properties1映射, properties2为空。

MyElement[1] 包括用一些属性填充的properties2映射, properties1为空。

反之亦然,我不知道哪些 MyElelmet 内部地图为空,哪些不是。

我想检查 map 中的每个 MyElement 并从每个元素中组装 properties1 或 properties2,以防它不为空。

结果应该是两个单独的地图(新集合)

Map <String, Property1> assembledProperties1;
Map <String, Property2> assembledProperties2;

您可以将其视为将结果收集到多个输出(assembledProperties1、assembledProperties2)。

有没有什么优雅的方法可以用 Java 流来做,没有丑陋的 if 语句?

由于不想将MyElement用作可变容器,因此您可以定义一种特殊类型的对象,该对象将携带对属性映射的引用。

为了能够使用此对象对MyElement类型的流执行可变归约,我们需要定义一个方法,该方法期望MyElement作为参数来根据流的下一个元素更新地图,以及另一个需要的方法并行合并部分执行结果(即合并两个对象)。

public class PropertyWrapper {
    private Map<String, Property1> properties1 = new HashMap<>();
    private Map<String, Property2> properties2 = new HashMap<>();
    
    public PropertyWrapper merge(MyElement element) {
        if (element.getProperties1() != null) properties1.putAll(element.getProperties1());
        if (element.getProperties2() != null) properties2.putAll(element.getProperties2());
        return this;
    }
        
    public PropertyWrapper merge(PropertyWrapper other) {
        this.properties1.putAll(other.getProperties1());
        this.properties2.putAll(other.getProperties2());
        return this;
    }

    // getters and toString()
}

这样,实际的代码可能如下所示:

public static void main(String[] args) {
    Map<String, MyElement> sourceMap =
        Map.of("key1", new MyElement(Map.of("a", new Property1("a"), "b", new Property1("b")), null),
               "key2", new MyElement(null, Map.of("c", new Property2("c"), "d", new Property2("d"))));

    PropertyWrapper result = sourceMap.values().stream()
        .collect(
            PropertyWrapper::new,
            PropertyWrapper::merge,
            PropertyWrapper::merge);

    System.out.println(result.getProperties1());
    System.out.println(result.getProperties2());
}

输出

{a=Property1{a}, b=Property1{b}}
{d=Property2{d}, c=Property2{c}}

另请注意,避免保留对集合的可为空引用是一种很好的做法。 如果这些字段将始终使用空集合初始化,则将消除空值检查的需要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM