如何在不覆盖集合的情况下将多个地图放在一起 <Character, Set<String>>

在我的项目中,我使用了两张地图Map<Character, Set<String>>.


map1 - is temporally holding needed values

map2 - is summing all data from map1 after each loop

例如我得到:


map2 = (B; Beryllium, Boron, Bromine)

map2 = (H; Hellum, Hydrogen, Hafnium)

现在新的 map1 是:


map1 = (B; Bismuth)

map1 = (O; Oxygen)

在我的代码中添加氧气作为新条目是可以的,但是通过覆盖值中的现有数据并只留下铋来为 B 添加新条目结束。


我的代码:


 while (iterator.hasNext()) {

   Set<String> words = new TreeSet<>();

   String word = iterator.next();

   char[] wordChars = word.toCharArray();


//some code


   words.add(word);

   map1.put(wordChars[i], words);


}

map2.putAll(map1);

我很难使用 .merge,但我不知道如何将它与 Sets 作为值一起使用,而且我不能将简单的字符串与 concat 一起使用。


侃侃无极
浏览 133回答 4
4回答

慕仙森

您可以像这样使用Map#merge :Map<String, Set<String>> map1; // [key="B";values=["Beryllium", "Boron", "Bromine"]]Map<String, Set<String>> map2; // [key="B";values=["Bismuth"] key="I";values=["Iron"]]for (Entry<String, Set<String>> entry : map2.entrySet()) {   map1.merge(entry.getKey(), entry.getValue(), (s1, s2) -> {s1.addAll(s2); return s1;});}//map1 = [key="B";values=["Beryllium", "Boron", "Bromine", "Bismuth"] key="I";values=["Iron"]]

慕虎7371278

在这种情况下不需要临时 map1。获取该字符的集合,如果为空则创建一个新集合。将单词添加到该集合并放入地图中:&nbsp;while (iterator.hasNext()) {&nbsp; &nbsp;String word = iterator.next();&nbsp; &nbsp;//some code&nbsp;&nbsp; &nbsp;Set<String> words = map2.get(word.charAt(0));&nbsp; &nbsp;if(words == null) {&nbsp; &nbsp; &nbsp;words = new TreeSet<>();&nbsp; &nbsp;}&nbsp; &nbsp;words.add(word);&nbsp; &nbsp;map2.put(word.charAt(0), words);}

MM们

使用 merge() 函数时,如果指定的键尚未与值相关联或值为空,则它将键与给定值相关联。否则,即如果键与一个值相关联,它会用给定的重映射函数的结果替换该值。因此,为了不覆盖旧值,您必须编写重新映射函数,以便它结合旧值和新值。为此,请替换此行:map2.putAll(map1);&nbsp; &nbsp;和map1.forEach( (key, value)->{&nbsp; &nbsp; &nbsp; &nbsp; map2.merge(key, value, (value1,value2) -> Stream.of(value1,value2)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .flatMap(Set::stream)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toSet()));&nbsp; &nbsp; });这将遍历 map1 并将不存在的 echh 键添加到 map2 并将其与给定值相关联,并且对于已经存在的每个键,它将旧值和新值组合在一起。或者你也可以使用Map.computeIfPresent和Map.putIfAbsentmap1.forEach( (key, value)->{&nbsp; &nbsp; &nbsp; &nbsp; map2.computeIfPresent(key, (k,v) -> Stream.of(v,value).flatMap(Set::stream).collect(Collectors.toSet()));&nbsp; &nbsp; &nbsp; &nbsp; map2.putIfAbsent(key, value);&nbsp; &nbsp; });

30秒到达战场

Map::compute可能是你要找的。这为您提供了一种映射任何现有值(如果有的话)的方法,或者如果没有则提供一个。例如,在您的情况下,类似以下内容可能就足够了:oldMap.compute("B", current -> {    if (current == null) {        // No existing entry, so use newMap's one        return newMap.get("B");    } else {        // There was an existing value, so combine the Sets        final Set<String> newValue = new HashSet<>(current);        newValue.addAll(newMap.get("B"));        return newValue;    }});还有分别来自 spring 和 guava 的MultiValueMapand Multimap(如果你可以引入依赖项的话)它们已经用更少的工作覆盖了这个案例。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java