Java 如何计算多重映射中每个值的出现次数?(爪哇)

Java 如何计算多重映射中每个值的出现次数?(爪哇),java,hashmap,guava,multimap,Java,Hashmap,Guava,Multimap,我有Multimap,它包含两个字符串。例如: 1 = [key,car], 2 = [key,blue], 3 = [key,car] List<String> myList = List.of("key", "car"); // java 9 多重映射定义(我使用的是Guava库): 但是我没有得到正确的结果。请尝试此代码map\u multi.get(key).size()是您的答案 ListMultimap<Integer, String> map_mu

我有
Multimap
,它包含两个字符串。例如:

1 = [key,car],  
2 = [key,blue],
3 = [key,car]
 List<String> myList = List.of("key", "car"); // java 9
多重映射定义(我使用的是Guava库):


但是我没有得到正确的结果。

请尝试此代码
map\u multi.get(key).size()
是您的答案

ListMultimap<Integer, String> map_multi = ArrayListMultimap.create();
map_multi.put(1, "car");
map_multi.put(2, "blue");
map_multi.put(3, "apple");
map_multi.put(1, "car");

for (Integer key : map_multi.keySet()) {
    System.out.println(map_multi.get(key).get(0) + " occurances: " + map_multi.get(key).size());
}

因此,第一步是从
ListMultimap
创建
Map
。您可以通过以下方式执行此操作:

Map<Integer, List<String>> collect = map_multi.entries()
            .stream()
            .collect(Collectors.groupingBy(Map.Entry::getKey,
                     Collectors.mapping(Map.Entry::getValue,
                                        Collectors.toList())));
您只需遍历映射的
values()
,并检查
myList
是否包含映射列表中的所有元素

long count = collect.values()
            .stream()
            .filter(list -> list.containsAll(myList))
            .count();

我认为您使用了错误的集合来存储数据。根据您编写的内容,您需要一个带有整数键和两个元素元组作为值的映射,然后使用它来计算频率:

Multiset
是一个支持顺序独立相等的集合,如
Set
,但可能有重复的元素。多集有时也称为包

多集合中彼此相等的元素称为同一单个元素的引用一个元素在多集合中出现的总数称为该元素的计数(术语“频率”和“多重性”是等效的,但在本API中未使用)

下面的代码假设您有两个元素元组的正确实现(aka pair,或您的
存储
类,但有正确的
等于
哈希代码
实现),例如:


通过创建一个以多重贴图值为关键点、以计数为值的贴图,可以实现所需:

Map<Collection<String>, Long> result = map_multi.asMap().values().stream()
    .collect(Collectors.groupingBy(v -> v, Collectors.counting()));

此方法通过计算其出现次数来累积相等的值。

您的多重映射定义是什么样子的?@ramazankul我已经编辑了我的帖子您想计算多重映射中的所有不同元组吗?为什么不将它们全部添加到一个集合中并得到它的大小呢?@Antonanasjew我想计算相同的发生率,而不是多重映射中有多少不同的元组。:)由于您的问题有点模糊,如果您也能为您的示例显示所需的输出,那将是非常有帮助的。@Schidu Luca是的,我需要比较存储在同一个键下的两个字符串(multimap entry的值)和存储在同一个键下的另一个值a,因此这个答案不是我想要的解决方案,在本例中,我们只寻找一个字符串,并对其进行比较。您在问题中说:“我想计算多重映射中相同值的发生次数”。当您执行“map_multi.get(key)”时,您将获得连接此键的所有值。在此之后,您可以比较所有值。@ramazankul-hmm我会检查这个out@ramazankul我认为这只是计算一个键下的值的数量,不完全是我想要的。我认为这就是解决方案。但正如我所读到的,首先实现Map并不是一件容易的事,而不是转换它。这应该给我同样的结果,对吗@Schidu-LucaWhole的第一个转换是
ListMutlimap
的内置功能:使用(获取
Map
视图)或(获取类型强制
Map
视图)。我认为这应该是个窍门,但我有一个noobies问题。我不知道如何将jooq导入到Netbeans:(您实际上不必使用jOOL,您可以自己编写这个类(类似于您的
存储
)-同样,它所需要的只是适当的
hashCode
equals
实现。我已经编辑了答案。
Map<Integer, List<String>> collect = map_multi.entries()
            .stream()
            .collect(Collectors.groupingBy(Map.Entry::getKey,
                     Collectors.mapping(Map.Entry::getValue,
                                        Collectors.toList())));
 List<String> myList = List.of("key", "car"); // java 9
long count = collect.values()
            .stream()
            .filter(list -> list.containsAll(myList))
            .count();
HashMap<Integer, Tuple2<String, String>> m = new HashMap<>();
Tuple2<String, String> carTuple = new Tuple2<>("key", "car");
Tuple2<String, String> blueTuple = new Tuple2<>("key", "blue");

m.put(1, carTuple);
m.put(2, blueTuple);
m.put(3, carTuple);

ImmutableMultiset<Tuple2<String, String>> occurrences = 
    ImmutableMultiset.copyOf(m.values());
System.out.println(occurrences); // [(key, car) x 2, (key, blue)]
ListMultimap<Integer, Tuple2<String, String>> m = ArrayListMultimap.create();
public class Tuple2<T1, T2> {

  public final T1 v1;
  public final T2 v2;

  public Tuple2(T1 v1, T2 v2) {
    this.v1 = v1;
    this.v2 = v2;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof Tuple2)) {
      return false;
    }
    @SuppressWarnings({"unchecked", "rawtypes"}) final Tuple2<T1, T2> that = (Tuple2) o;
    return Objects.equals(v1, that.v1) && Objects.equals(v2, that.v2);
  }

  @Override
  public int hashCode() {
    return Objects.hash(v1, v2);
  }

  @Override
  public String toString() {
    return "(" + v1 + ", " + v2 + ")";
  }
}
Map<Collection<String>, Long> result = map_multi.asMap().values().stream()
    .collect(Collectors.groupingBy(v -> v, Collectors.counting()));
Map<Collection<String>, Integer> result = new HashMap<>();
map_multi.asMap().values().forEach(v -> result.merge(v, 1, Integer::sum));