如何正确使用map<字符串,StringBuilder>的方法merge()来附加特定字符?



我有以下地图:

Map<String, StringBuilder> map1 = new HashMap<>();
Map<String, StringBuilder> map2 = new HashMap<>();
StringBuilder sb11 = new StringBuilder("0004001:00:00;0004002:00:00;0004002:01:01;");
StringBuilder sb12 = new StringBuilder("0005001:00:00;0005002:00:00;0005002:01:01;");
StringBuilder sb13 = new StringBuilder("0007001:00:00;0007002:00:00;0007002:01:01;");

map1.put("0004", sb11);
map1.put("0005", sb12);
map1.put("0007", sb13);

StringBuilder sb21 = new StringBuilder("0004002:00:00;0004002:00:00;0004002:01:01;");
StringBuilder sb22 = new StringBuilder("0007002:00:00;0007002:00:00;0007002:01:01;");
StringBuilder sb23 = new StringBuilder("0008002:00:00;0008002:00:00;0008002:01:01;");

map2.put("0004", sb21);
map2.put("0007", sb22);
map2.put("0008", sb23);

在这些映射的基础上,我需要获得一个结果映射,对于上面两个映射中的相同键,该映射具有由"|"分隔的值串联。

对于不同的键,还必须满足条件 - 如果键仅存在于 map1 中,则仅添加值,如果键仅存在于 map2 中,则应在值之前添加"|"。简而言之,我的意思是这个结果:

地图1

0004 - 0004001:00:00;0004002:00:00;0004002:01:01;
0005 - 0005001:00:00;0005002:00:00;0005002:01:01;
0007 - 0007001:00:00;0007002:00:00;0007002:01:01;

地图2

0004 - 0004002:00:00;0004002:00:00;0004002:01:01;
0007 - 0007002:00:00;0007002:00:00;0007002:01:01;
0008 - 0008002:00:00;0008002:00:00;0008002:01:01;

预期成果图

0004 - 0004001:00:00;0004002:00:00;0004002:01:01;|0004002:00:00;0004002:00:00;0004002:01:01;
0005 - 0005001:00:00;0005002:00:00;0005002:01:01;
0007 - 0007001:00:00;0007002:00:00;0007002:01:01;|0007002:00:00;0007002:00:00;0007002:01:01;
0008 - |0008002:00:00;0008002:00:00;0008002:01:01;

我几乎设法找到了一个解决方案,但是当键仅存在于map2中时,我遇到了问题,我不知道如何更改我的代码,以便在值前面添加"|"符号。

我该如何解决它?

我的代码:

public static void main(String args[]) {
Map<String, StringBuilder> map1 = new HashMap<>();
Map<String, StringBuilder> map2 = new HashMap<>();
StringBuilder sb11 = new StringBuilder("0004001:00:00;0004002:00:00;0004002:01:01;");
StringBuilder sb12 = new StringBuilder("0005001:00:00;0005002:00:00;0005002:01:01;");
StringBuilder sb13 = new StringBuilder("0007001:00:00;0007002:00:00;0007002:01:01;");

map1.put("0004", sb11);
map1.put("0005", sb12);
map1.put("0007", sb13);

StringBuilder sb21 = new StringBuilder("0004002:00:00;0004002:00:00;0004002:01:01;");
StringBuilder sb22 = new StringBuilder("0007002:00:00;0007002:00:00;0007002:01:01;");
StringBuilder sb23 = new StringBuilder("0008002:00:00;0008002:00:00;0008002:01:01;");

map2.put("0004", sb21);
map2.put("0007", sb22);
map2.put("0008", sb23);

//Merge maps
map2.forEach((key, value) -> map1.merge(key, value, (v1, v2) -> v1.append("|").append(v2)));

map1.entrySet().forEach(entry->{
System.out.println(entry.getKey() + " " + entry.getValue());  
});
}

结果:

0007 0007001:00:00;0007002:00:00;0007002:01:01;|0007002:00:00;0007002:00:00;0007002:01:01;
0004 0004001:00:00;0004002:00:00;0004002:01:01;|0004002:00:00;0004002:00:00;0004002:01:01;
0005 0005001:00:00;0005002:00:00;0005002:01:01;
0008 0008002:00:00;0008002:00:00;0008002:01:01;

merge根本无法完成这项工作。merge只有在map1map2都具有提供的密钥时才会调用该函数;否则,如果两个映射中只有一个具有该键的映射,则仅插入该映射,无需修改 - 因此,没有前导|。没有办法使merge以不同的方式工作,所以你不能在这里使用它。摆脱它。

像往常一样,如果您仅在看起来明显获胜的地方使用 lambda,而不是作为通用锤子,那么阅读起来会更简单,它是如此之好,以至于您想将其用于所有事情,包括给面包涂黄油。

for (var entry : map2.entrySet()) {
map1
.computeIfAbsent(entry.getKey(), x -> new StringBuilder())
.append("|")
.append(entry.getValue());
}

足够简单,并且完全按照您的要求。

如果你真的一心想用那把锤子抹这片面包,你真正想要的方法就是compute。不过,你将不得不弄乱null,它不会更漂亮。

注意:collection.forEach,以及collection.stream.forEach糟糕的代码风格 - 你失去了局部变量,控制流和异常透明度,你在交易中绝对没有任何收获。为什么要选择严格劣质的选项?如果您发现可以接受转储,例如someList.forEach(System.out::println);一行,我很难想象您可能愿意为不允许for (var v : someList) System.out.println(v);提供什么样的非疯狂论据,这同样简短,并且可以更好地处理本地变量、控制流和检查异常。我已经为您完成了删除该位的服务。正如我所说,当 lambda 给你带来一些有形的东西时,请使用 lambda,比如上面的computeIfAbsent。如果没有他们,那会更加复杂。

好吧,这就是我想出的。它只是遍历一个映射,检查键并将适当的值放入另一个映射中。 如果每个映射包含相同的键,则put,两者都在map1中用|分隔,否则,将map2 keyvalue与带有|prefixed放在map1中。

for(String key : map2.keySet()) {
if (map1.containsKey(key)) {
map1.put(key, map1.get(key).append("|").append(map2.get(key)));
} else {
map1.put(key, map2.get(key).insert(0, "|"));
}
}

map1.entrySet().forEach(System.out::println);

指纹

0007=0007001:00:00;0007002:00:00;0007002:01:01;|0007002:00:00;0007002:00:00;0007002:01:01;
0004=0004001:00:00;0004002:00:00;0004002:01:01;|0004002:00:00;0004002:00:00;0004002:01:01;
0005=0005001:00:00;0005002:00:00;0005002:01:01;
0008=|0008002:00:00;0008002:00:00;0008002:01:01;

如果您希望它们按键排序,请将map1设为TreeMap

相关内容

  • 没有找到相关文章

最新更新