首页 > 解决方案 > 按特定顺序合并两个地图

问题描述

我有两个地图 map1 和 map2。我想按特定顺序组合这两个地图。假设我有两张地图

Map<String, String> map1 = new HashMap<>();
Map<String, String> map2 = new HashMap<>();

map1.put("id1", "3895");
map1.put("id2", "6754");
map1.put("id3", "7896");
map1.put("id4", "1122");

map2.put("month1", "Jan");
map2.put("month2", "Mar");
map2.put("month3", "Dec");
map2.put("month4", "Aug");

现在我想组合这两张地图,以便第三张地图的元素按以下顺序排列。Map3 中的预期顺序。

("id1", "3895")
("month1", "Jan")
("id2", "6754")
("month2", "Mar")
("id3", "7896")
("month3", "Dec")
("id4", "1122")
("month4", "Aug")

我如何实现这一目标?我尝试使用 putAll 和 LinkedHashMap 但结果顺序不是预期的。

使用 LinkedHashMap -

Map<String, String> merged = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new));

结果是

("id1", "3895")
("id2", "6754")
("id3", "7896")
("id4", "1122")
("month1", "Jan")
("month2", "Mar")
("month3", "Dec")
("month4", "Aug")

这不是我的预期。

标签: javacollectionsjava-8hashmapjava-stream

解决方案


正如@Andreas 所建议的,您可以并行迭代地图并LinkedHashMap保持秩序,

Map<String, String> result = new LinkedHashMap<>();
Iterator<Map.Entry<String, String>> iter1 = map1.entrySet().iterator();
Iterator<Map.Entry<String, String>> iter2 = map2.entrySet().iterator();
while(iter1.hasNext() || iter2.hasNext()) {
    Map.Entry<String, String> e1 = iter1.next();
    Map.Entry<String, String> e2 = iter2.next();

    result.put(e1.getKey(), e1.getValue());
    result.put(e2.getKey(), e2.getValue());

}

如果两个地图的键都像 id1、id2、month1、month2,那么您可以使用Comparator带数字的自定义进行排序,如下所示,

Comparator<Map.Entry<String, String>> comparator = Comparator.comparing(c -> c.getKey().replaceAll("^\\D+", ""))  ;
Map<String, String> collect = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
        .sorted(comparator)
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,(oldValue, newValue) -> oldValue, LinkedHashMap::new));

推荐阅读