将 Map 中的重复值映射到它们所在的键
Mapping duplicate values from Map against the keys in which they are found
我有的是,
Map<String, String> map = new HashMap<>();
map.put("Shop1", "Product1");
map.put("Shop2", "Product2");
map.put("Shop3", "Product1");
map.put("Shop4", "Product2");
map.put("Shop5", "Product3");
我想要的是,
Map<String, List<String>> result = new HashMap<>();
其中result
包含,
产品 1 -> 店铺 1,店铺 3
Product2 -> Shop2,Shop4
这里 Product1 在商店 Shop1 和 Shop3 中多次被发现,Product2 在商店 Shop2 和 Shop4 中多次被发现。任何帮助将不胜感激。
您要做的是反转映射(值变成键,键按旧值分组)。应该有这样做的图书馆,但是一个带有流的示例解决方案:
result = map.entrySet()
.stream()
.filter(e -> Collections.frequency(map.values(), e.getValue()) > 1)
.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())))
您可以使用 Guava's Multimap 来做到这一点。
final Map<String, String> map = new HashMap<>();
map.put("Shop1", "Product1");
map.put("Shop2", "Product2");
map.put("Shop3", "Product1");
map.put("Shop4", "Product2");
map.put("Shop5", "Product3");
final Multimap<String, String> shopToProduct = Multimaps.forMap(map), productToShop = HashMultimap.create();
Multimaps.invertFrom(shopToProduct, productToShop);
// Prints the output you want
productToShop.asMap().entrySet().forEach(System.out::println);
// You can also get the backing map, but ideally use the Multimap abstraction
final Map<String, Collection<String>> backingMap = productToShop.asMap();
首先找到 distinct
个值。之后,您可以遍历每个值并在地图上搜索它们的 key
,每当您找到 key
时,只需将它们放入 list
.
List<String> list = map.values().stream().distinct().collect(Collectors.toList()); //Collecting the distinct values
for (String value : list) { //iterating through each key
List<String> temp = map.entrySet()
.stream()
.filter(entry -> value.equals(entry.getValue())) //filtering out similar entries
.map(Map.Entry::getKey)
.collect(Collectors.toList());
result.put(value, temp);
}
System.out.println(result);
您可以使用 Guava 的 Multimap 来实现此目的,但是您需要反转地图。
Multimap<String, String> map = HashMultimap.create();
map.put("Product1", "Shop1");
map.put("Product2", "Shop2");
map.put("Product2", "Shop1");
map.put("Product2", "Shop4");
map.put("Product3", "Shop5");
System.out.println(map.get("Product2")); // [Shop4, Shop1, Shop2]
或者,如果您不想反转原始地图 - 您可以使用 Map<String, List<String>
(或将以下解决方案与上面的 Multimap
结合使用)并使用 [=14 添加记录=],然后反转地图以获得您想要的值。
Map<String, List<String>> map = new HashMap<>();
map.computeIfAbsent("Shop1", (x) -> new ArrayList<>()).add("Product1");
map.computeIfAbsent("Shop2", (x) -> new ArrayList<>()).add("Product2");
map.computeIfAbsent("Shop3", (x) -> new ArrayList<>()).add("Product1");
map.computeIfAbsent("Shop4", (x) -> new ArrayList<>()).add("Product2");
map.computeIfAbsent("Shop5", (x) -> new ArrayList<>()).add("Product3");
// Invert the map
Map<String, List<String>> invertedMap = map
.entrySet()
.stream()
.collect(HashMap::new, (m, entry) -> {
entry.getValue().forEach((value) -> {
m.computeIfAbsent(value, (x) -> new ArrayList<>()).add(entry.getKey());
});
}, Map::putAll);
System.out.println(invertedMap); // {Product3=[Shop5], Product1=[Shop1, Shop3], Product2=[Shop4, Shop2]}
我有的是,
Map<String, String> map = new HashMap<>();
map.put("Shop1", "Product1");
map.put("Shop2", "Product2");
map.put("Shop3", "Product1");
map.put("Shop4", "Product2");
map.put("Shop5", "Product3");
我想要的是,
Map<String, List<String>> result = new HashMap<>();
其中result
包含,
产品 1 -> 店铺 1,店铺 3
Product2 -> Shop2,Shop4
这里 Product1 在商店 Shop1 和 Shop3 中多次被发现,Product2 在商店 Shop2 和 Shop4 中多次被发现。任何帮助将不胜感激。
您要做的是反转映射(值变成键,键按旧值分组)。应该有这样做的图书馆,但是一个带有流的示例解决方案:
result = map.entrySet()
.stream()
.filter(e -> Collections.frequency(map.values(), e.getValue()) > 1)
.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())))
您可以使用 Guava's Multimap 来做到这一点。
final Map<String, String> map = new HashMap<>();
map.put("Shop1", "Product1");
map.put("Shop2", "Product2");
map.put("Shop3", "Product1");
map.put("Shop4", "Product2");
map.put("Shop5", "Product3");
final Multimap<String, String> shopToProduct = Multimaps.forMap(map), productToShop = HashMultimap.create();
Multimaps.invertFrom(shopToProduct, productToShop);
// Prints the output you want
productToShop.asMap().entrySet().forEach(System.out::println);
// You can also get the backing map, but ideally use the Multimap abstraction
final Map<String, Collection<String>> backingMap = productToShop.asMap();
首先找到 distinct
个值。之后,您可以遍历每个值并在地图上搜索它们的 key
,每当您找到 key
时,只需将它们放入 list
.
List<String> list = map.values().stream().distinct().collect(Collectors.toList()); //Collecting the distinct values
for (String value : list) { //iterating through each key
List<String> temp = map.entrySet()
.stream()
.filter(entry -> value.equals(entry.getValue())) //filtering out similar entries
.map(Map.Entry::getKey)
.collect(Collectors.toList());
result.put(value, temp);
}
System.out.println(result);
您可以使用 Guava 的 Multimap 来实现此目的,但是您需要反转地图。
Multimap<String, String> map = HashMultimap.create();
map.put("Product1", "Shop1");
map.put("Product2", "Shop2");
map.put("Product2", "Shop1");
map.put("Product2", "Shop4");
map.put("Product3", "Shop5");
System.out.println(map.get("Product2")); // [Shop4, Shop1, Shop2]
或者,如果您不想反转原始地图 - 您可以使用 Map<String, List<String>
(或将以下解决方案与上面的 Multimap
结合使用)并使用 [=14 添加记录=],然后反转地图以获得您想要的值。
Map<String, List<String>> map = new HashMap<>();
map.computeIfAbsent("Shop1", (x) -> new ArrayList<>()).add("Product1");
map.computeIfAbsent("Shop2", (x) -> new ArrayList<>()).add("Product2");
map.computeIfAbsent("Shop3", (x) -> new ArrayList<>()).add("Product1");
map.computeIfAbsent("Shop4", (x) -> new ArrayList<>()).add("Product2");
map.computeIfAbsent("Shop5", (x) -> new ArrayList<>()).add("Product3");
// Invert the map
Map<String, List<String>> invertedMap = map
.entrySet()
.stream()
.collect(HashMap::new, (m, entry) -> {
entry.getValue().forEach((value) -> {
m.computeIfAbsent(value, (x) -> new ArrayList<>()).add(entry.getKey());
});
}, Map::putAll);
System.out.println(invertedMap); // {Product3=[Shop5], Product1=[Shop1, Shop3], Product2=[Shop4, Shop2]}