在Multimap中计算重复值

时间:2018-03-22 06:41:01

标签: java count guava multimap

我有Multimap。例如:

00254=[00255, 2074E, 2074E, 2074E, 2074E, 2074E, 2074E, 00010, 00010, 00010, 0006, 0006, 0006, 00010, R01018, R01018, 0006, 0006, R01018, R01018, R01018, 12062, S2202962, S2202962, R01018, 12062, 20466, 12062, 20466, 22636, 20466, 20466, 22636, 22636, 22636, 22636, 22636, 22636, 22636, 22636, 00255, 2074E, 2074E, 2074E, 2074E, 2074E]
00256=[00257, 2074E, 2074E, 2074E, 2074E, 00010, 2074E, 2074E, 0006, 00010, 00010, 00010, 0006, 0006, 0006, R01018, R01018, 0006, R01018, R01018, R01018, 12062, S2202962, S2202962, R01018, 12062, 20466, 12062, 20466, 20466, 20466, 22636, 22636, 22636, 22636, 22636, 22636, 22636, 22636, 22636, 00257, 2074E, 2074E, 2074E, 2074E, 00010]

我想获得包含重复值的值的数量。

  • 00254 = [00255:2,2074E:11,00010:4,006:5,R01018:6,...]
  • 00256 = [00257:2,2074E:10,000-2:5,000:5,R01018:7,...]

是否可以获得重复的数字?

感谢。

2 个答案:

答案 0 :(得分:3)

使用Java 8 Stream获取特定值的出现的解决方案,只需获取值Collection,然后对值和计数进行分组(使用Collectors函数)以获取{ {1}}:

Map<String, Long>
  

1:{bar = 1,foo = 2}

     

2:{Hello = 1,foo = 1,World = 2}

这将生成Multimap<Integer, String> maps = ArrayListMultimap.create(); maps.put(1, "foo"); maps.put(1, "bar"); maps.put(1, "foo"); maps.put(2, "Hello"); maps.put(2, "foo"); maps.put(2, "World"); maps.put(2, "World"); Here is the idea to print the occurences per value : maps.keySet().stream() //Iterate the `keys` .map(i -> i + " : " + //For each key maps.get(i).stream() //stream the values. .collect( //Group and count Collectors.groupingBy( Function.identity(), Collectors.counting() ) ) ) .forEach(System.out::println); ,我让您根据自己的需要进行调整。

答案 1 :(得分:2)

计算出现次数是Multiset的完美用例,即

  

支持与订单无关的平等的集合,例如Set,但可能包含重复的元素。 multiset有时也被称为包。

     

多个集合中彼此相等的元素称为相同单个元素的出现。

您可以选择几个不同的Multiset implementations,以及几个方便的set-like methods in Multisets helper class

在这里,您可以1)收集到multiset或2)使用具有多集值的自定义多图。

  1. 您可以收集不可变的多重集:而不是分组到地图:

    ImmutableMultiset<String> qtyMultiset = multimap.get(key).stream()
        .collect(ImmutableMultiset.toImmutableMultiset());
    

    或可变的:

    HashMultiset<String> qtyMultiset = multimap.get(key).stream()
        .collect(Multisets.toMultiset(Function.identity(), e -> 1, HashMultiset::create));
    
  2. 或许你可以在第一时间使用自定义多图? (不幸的是,没有任何MultisetMultimap接口和实现,因此需要自定义实例):

    Multimap<String, String> countingMultimap
        = Multimaps.newMultimap(new LinkedHashMap<>(), LinkedHashMultiset::create);
    

    如果您不需要保留订单,则可以删除Linked部分。对于您的数据:

    countingMultimap.putAll("00254", ImmutableList.of("00255", "2074E", "2074E", "2074E", "2074E", "2074E", "2074E", "00010", "00010", "00010", "0006", "0006", "0006", "00010", "R01018", "R01018", "0006", "0006", "R01018", "R01018", "R01018", "12062", "S2202962", "S2202962", "R01018", "12062", "20466", "12062", "20466", "22636", "20466", "20466", "22636", "22636", "22636", "22636", "22636", "22636", "22636", "22636", "00255", "2074E", "2074E", "2074E", "2074E", "2074E"));
    countingMultimap.putAll("00256", ImmutableList.of("00257", "2074E", "2074E", "2074E", "2074E", "00010", "2074E", "2074E", "0006", "00010", "00010", "00010", "0006", "0006", "0006", "R01018", "R01018", "0006", "R01018", "R01018", "R01018", "12062", "S2202962", "S2202962", "R01018", "12062", "20466", "12062", "20466", "20466", "20466", "22636", "22636", "22636", "22636", "22636", "22636", "22636", "22636", "22636", "00257", "2074E", "2074E", "2074E", "2074E", "00010"));
    

    返回的multimap将是:

    {00254=[00255 x 2, 2074E x 11, 00010 x 4, 0006 x 5, R01018 x 6, 12062 x 3, S2202962 x 2, 20466 x 4, 22636 x 9], 00256=[00257 x 2, 2074E x 10, 00010 x 5, 0006 x 5, R01018 x 6, 12062 x 3, S2202962 x 2, 20466 x 4, 22636 x 9]}
    
  3. 有关详细信息,请阅读Guava Wiki page about Multiset(使用字数作为示例)。