如何将一个地图中的元素添加到另一个地图中,如果它们不存在或值为空?

huangapple go评论90阅读模式
英文:

How do I add elements from one map to another if it doesn't exist already or the value is blank?

问题

在我的Spring Boot应用程序中,我有两个Map:

Map<String, String> defaultValuesMap = Map.of(
    "BMW", "Something",
    "Audi", "Something else",
    "Nissan", "Something else"
);

Map<String, String> myMap = Map.of(
    "Mercedes", "Something",
    "Suzuki", "Whatever",
    "Audi", "Dummy data",
    "Nissan", ""
);

我正在尝试创建一些逻辑,以便遍历defaultValuesMap中的所有条目,并如果该条目不存在于myMap中或者存在但值为空,则用defaultValuesMap中的键/值对替换它。

结果应该如下所示:

Map<String, String> myMap = Map.of(
    "Mercedes", "Something",
    "Suzuki", "Whatever",
    "Audi", "Dummy data",
    "Nissan", "Something else",
    "BMW", "Something"
);

我尝试了类似以下的代码:

defaultValuesMap.entrySet()
    .stream()
    .map(entry -> {
        if (!myMap.containsKey(entry.getKey()) || myMap.get(entry.getKey()).isBlank()) {
            myMap.put(entry.getKey(), entry.getValue());
        }
        return entry;
    });

这不起作用,然后我尝试在末尾添加collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)),但这会替换元素,即使它们不是缺失或空的情况下也会替换...

英文:

In my Spring Boot application I have two Maps:

Map&lt;String, String&gt; defaultValuesMap = Map.of(
    &quot;BMW&quot;, &quot;Something&quot;,
    &quot;Audi&quot;, &quot;Something else&quot;,
    &quot;Nissan&quot;, &quot;Something else&quot;
);

Map&lt;String, String&gt; myMap = Map.of(
    &quot;Mercedes&quot;, &quot;Something&quot;,
    &quot;Suzuki&quot;, &quot;Whatever&quot;,
    &quot;Audi&quot;, &quot;Dummy data&quot;,
    &quot;Nissan&quot;, &quot;&quot;
);

I'm trying to make some logic that takes alle the Entries in defaultValuesMap and say if that entry does not exist in myMap OR it exists but the value is blank, then replace that key/value pair with the one from defaultValuesMap.

The result would look like this:

Map&lt;String, String&gt; myMap = Map.of(
    &quot;Mercedes&quot;, &quot;Something&quot;,
    &quot;Suzuki&quot;, &quot;Whatever&quot;,
    &quot;Audi&quot;, &quot;Dummy data&quot;,
    &quot;Nissan&quot;, &quot;Something else&quot;,
    &quot;BMW&quot;, &quot;Something&quot;
);

I've tried something like this:

defaultValuesMap.entrySet()
    .stream()
    .map(entry -&gt; {
        if (!myMap.containsKey(entry) || myMap.get(entry).isBlank)
                        myMap.put(
                                entry.getKey(),
                                entry.getValue());
                    return entry;
                });

This didn't work, then I tried to add collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); to the end of it but then it just replaced the elements even if they were not missing or blank...

答案1

得分: 3

Map.of 返回一个不可修改的地图,正如其名称所示,不能被修改。

创建一个第三个结果地图,或者如果你想要在你的示例中直接执行,可以将第二个地图设置为可修改。然后,您可以使用 map.compute 来获得所需的结果:

Map<String, String> defaultValuesMap = Map.of(
        "BMW", "Something",
        "Audi", "Something else",
        "Nissan", "Something else");

Map<String, String> myMap = new HashMap<>(Map.of(
        "Mercedes", "Something",
        "Suzuki", "Whatever",
        "Audi", "Dummy data",
        "Nissan", ""));

defaultValuesMap.forEach((k, v) ->{
    myMap.compute(k, (k1, prev) -> prev == null || prev.isBlank() ? v : prev);
});

System.out.println(myMap);
英文:

Unmodifiable map

Map.of returns an unmodifiable map, which as the name implies cannot be modified.

Create a third result map or if you want to do it in place like in your example, make the second map modifiable. Then you can use map.compute to get the desired result:

Map&lt;String, String&gt; defaultValuesMap = Map.of(
        &quot;BMW&quot;, &quot;Something&quot;,
        &quot;Audi&quot;, &quot;Something else&quot;,
        &quot;Nissan&quot;, &quot;Something else&quot;);

Map&lt;String, String&gt; myMap = new HashMap&lt;&gt;(Map.of(
        &quot;Mercedes&quot;, &quot;Something&quot;,
        &quot;Suzuki&quot;, &quot;Whatever&quot;,
        &quot;Audi&quot;, &quot;Dummy data&quot;,
        &quot;Nissan&quot;, &quot;&quot;));

defaultValuesMap.forEach((k,v) -&gt;{
    myMap.compute(k, (k1, prev) -&gt; prev == null || prev.isBlank() ? v : prev);
});

System.out.println(myMap);

答案2

得分: 0

没有办法通过一个地图的迭代来实现这一点。原因是结果必须包括仅存在于一个地图中的映射(要么是myMap,要么是默认值地图),因此对一个地图的迭代将始终排除仅存在于另一个地图中的键。

因此,首先需要构建一个包含两个地图的键的并集的集合

Set<String> unionKeys = new HashSet<>(myMap.keySet());
unionKeys.addAll(defaultValuesMap.keySet());

这个集合是迭代的基础,可以使用三元运算符从myMap或默认值中获取值

Map<String, String> resultMap = unionKeys.stream()
    .collect(Collectors.toMap(
        Function.identity(),
        key -> myMap.containsKey(key) && !myMap.get(key).isBlank() ?
            myMap.get(key) : defaultValuesMap.get(key)
        )
    );
英文:

there is no way to achieve this with iteration on one map. the reason is that the result must include mapping that exists in only one map (either myMap or the default) so iteration on one map will always exclude keys that are present only in the other.

so first you need to construct a set that includes union of keys from both maps

	Set&lt;String&gt; unionKeys = new HashSet&lt;&gt;(myMap.keySet());
	unionKeys.addAll(defaultValuesMap.keySet());

this set is the basis of the iteration, the value can be taken using the ternary operator from myMap or the default

	Map&lt;String, String&gt; resultMap = unionKeys.stream()
		.collect(Collectors.toMap(
			Function.identity(),
			key -&gt; myMap.containsKey(key) &amp;&amp; !myMap.get(key).isBlank() ? 
				myMap.get(key) : defaultValuesMap.get(key)
			)
		);

huangapple
  • 本文由 发表于 2023年3月3日 19:09:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75626324.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定