如何在java中有效地求两个树Map的和?

ruarlubt  于 2021-05-30  发布在  Hadoop
关注(0)|答案(2)|浏览(432)

我有多个树状图,我只想在一个树状图求和值相同的关键和有效。比如:

TreeMap<String,Long> sum(TreeMap<String,Long> tm1,TreeMap<String,Long> tm2);

我试着做这个,但是我。我无法将列表再次转换为树状图和2。如果等于:

TreeMap<String,Long> tm1=new TreeMap<String, Long>();
    ...
    TreeMap<String,Long> tm2=new TreeMap<String, Long>();
    ...       
    List<Map.Entry<String,Long>> first = new ArrayList<Map.Entry<String,Long>>(tm1.entrySet());
    List<Map.Entry<String,Long>> second = new ArrayList<Map.Entry<String,Long>>(tm2.entrySet());
    Iterable<Map.Entry<String,Long>> all = Iterables.mergeSorted(
            ImmutableList.of(first, second), new Ordering<Map.Entry<String, Long>>() {
        @Override
        public int compare(java.util.Map.Entry<String, Long> stringLongEntry, java.util.Map.Entry<String, Long> stringLongEntry2) {
            return stringLongEntry.getKey().compareTo(stringLongEntry2.getKey());
        }
    });
    TreeMap<String,Long> mappedMovies = Maps.uniqueIndex(... ??)

编辑:我不能使用Java8,因为这个程序运行在只支持Java1.7的AmazonWeb服务中的hadoop程序中。

k2fxgqgv

k2fxgqgv1#

您可以使用Java8流来实现这一点。考虑以下代码:

// Testdata - The first map
Map<String, Long> m1 = new TreeMap<>();
m1.put("A", 1L);
m1.put("B", 1L);
m1.put("C", 1L);

// Testdata - The second map
Map<String, Long> m2 = new TreeMap<>();
m2.put("C", 2L);
m2.put("D", 2L);
m2.put("E", 2L);

// Summarize using streams
final Map<String, Long> summarized =
        Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())     // Stream both maps
              .collect(Collectors.groupingBy(                             // Collect the map
                          Map.Entry::getKey,                              // Group by key
                          Collectors.summingLong(Map.Entry::getValue)));  // Value is the sum

System.out.println("Summarized: " + summarized);                          // Print the output

总结 Map 按键分组,按值汇总。输出为:
总结:{a=1,b=1,c=3,d=2,e=2}
如果要将其放入函数中,只需执行以下操作:

public Map<String, Long> summarize(
        final Map<String, Long> m1, 
        final Map<String, Long> m2) {

    return Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
                 .collect(groupingBy(
                          Map.Entry::getKey,
                          summingLong(Map.Entry::getValue)));
}

要阅读有关Java8流的更多信息,请查看oracle文档。

mfuanj7w

mfuanj7w2#

以下函数计算总和:

public static TreeMap<String, Long> sum(TreeMap<String, Long> first,
        TreeMap<String, Long> second) {
    TreeMap<String, Long> result = new TreeMap<String, Long>(first);

    for (Entry<String, Long> e : second.entrySet()) {
        Long l = result.get(e.getKey());
        result.put(e.getKey(), e.getValue() + (l == null ? 0 : l));
    }

    return result;
}

测试代码:

TreeMap<String, Long> first = new TreeMap<String, Long>();
TreeMap<String, Long> second = new TreeMap<String, Long>();

first.put("x", 1L);
first.put("y", 5L);

second.put("x", 2L);
second.put("y", 3L);
second.put("z", 5L);

System.out.println(sum(first, second));

输出:

{x=3, y=8, z=5}

编辑
一个小的优化就是复制最大的 TreeMap 迭代最小的。这减少了查找/插入的数量。

public static TreeMap<String, Long> sum(TreeMap<String, Long> first,
        TreeMap<String, Long> second) {
    // optimization (copy the largest tree map and iterate over the
    // smallest)
    if (first.size() < second.size()) {
        TreeMap<String, Long> t = first;
        first = second;
        second = t;
    }

    TreeMap<String, Long> result = new TreeMap<String, Long>(first);

    for (Entry<String, Long> e : second.entrySet()) {
        Long l = result.get(e.getKey());
        result.put(e.getKey(), e.getValue() + (l == null ? 0 : l));
    }

    return result;
}

相关问题