在跳过Java中的第一个条目时合并两个TreeMaps

时间:2017-09-13 10:01:37

标签: java dictionary merge treemap

我想要合并两个TreeMaps:

TreeMap<foo, bar> map1 = {key1=value1, key2=value2};
TreeMap<foo, bar> map2 = {key1=value6, key3=value3, key4=value4, key5=value5};

我想将这些地图合并为一个地图,但我想跳过第二张地图的第一个条目,所以我会这样:

TreeMap<foo, bar> result = {key1=value1, key2=value2, key3=value3, key4=value4, key5=value5};

但是,我无法致电map2.remove(map2.firstKey())甚至map2.remove(key1),因为equalsfoo上无效。

有没有好办法呢?

(目前我正在做这个工作正常,但我对此并不满意,我不认为这是最好的方式:

TreeMap<foo, bar> result = new TreeMap<>();
result.putAll(map1);

for (Map.Entry<foo, bar> entry : Iterables.skip(map2.entrySet(), 1) ) {
  result.put(entry.getKey(), entry.getValue());
}

3 个答案:

答案 0 :(得分:2)

您可以使用tailMap

TreeMap<foo, bar> result = new TreeMap<>(map1);
result.putAll (map2.tailMap (map2.keySet().iterator().next(), false));

编辑:您无需找到第二个密钥。您可以使用包含== false的tailMap运行,并将第一个密钥传递给它,该密钥将被排除。

答案 1 :(得分:1)

最简单的方法是:

TreeMap<Foo, Bar> result = new TreeMap<>(map2);
result.putAll(map1);

你说这两个地图总是有第一个共同的元素,你似乎想要保留map1中的第一个值。因此,您需要做的只是整个地图的简单putAll,因此map1的第一个值会覆盖map2的第一个值。无需任何其他代码即可跳过map2的第一个条目。

更新:根据您的评论,看起来Foo的compareTo方法无效。因此,您需要创建自己的自定义Comparator,并将其传递给您创建的所有TreeMaps的constructors

您可以使用与此类似的代码:

Comparator<Foo> myFooComparator = Comparator
        .comparing(Foo::getName)
        .thenComparingInt(Foo::getScore);

TreeMap<Foo, Bar> result = new TreeMap<>(myFooComparator);
result.putAll(map2);
result.putAll(map1);

其中String Foo.getName()int Foo.getScore()是Foo的两个公共方法,用作比较两个Foo对象时需要比较的内容的示例。

答案 2 :(得分:0)

以下是对Streams(Java 8)的建议:

public static void main(String[] args) {
    TreeMap<String, String> map1 = new TreeMap<>();
    map1.put("key1", "value1");
    map1.put("key2", "value2");
    TreeMap<String, String> map2 = new TreeMap<>();
    map2.put("key1", "value6");
    map2.put("key3", "value3");
    map2.put("key4", "value4");
    map2.put("key5", "value5");
    String first = map2.entrySet().iterator().next().getKey();
    Map<String, String> res =
            Stream.of(map1.entrySet(), map2.entrySet().stream().filter(e -> !e.getKey().equals(first)).collect(Collectors.toList()))
                    .flatMap(Collection::stream)
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a.compareTo(b) >= 0 ? a : b, TreeMap::new));
    System.out.println(res);
}

打印:

{key1=value1, key2=value2, key3=value3, key4=value4, key5=value5}

使用此解决方案,两个输入映射不会更改。