HashMap<String, String> map = new HashMap<String, String>();
HashMap<String, String> newMap = new HashMap<String, String>();
map.put("A","1");
map.put("B","2");
map.put("C","2");
map.put("D","1");
预期输出:"AD"、"1"和"BC"、"2"存在于 newMap 中,这意味着,如果数据值相同,则需要通过在 newMap 中创建的组合其键来组合其键以只有一个数据值 如何在 Java 中实现这一点?
您希望使用Collectors.groupingBy
按"整数"值分组,并将以前的键收集为新值。默认情况下,分组产生List
。您可以进一步使用下游收集器Collectors.mapping
和另一个下游收集器Collectors.reducing
将各个项目(值)映射和连接为单个字符串。
Map<String, String> groupedMap = map.entrySet().stream()
.collect(Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(
Map.Entry::getKey,
Collectors.reducing("", (l, r) -> l + r))));
{1=AD, 2=BC}
现在,您可以使用最终结果的值切换键,尽管我真的认为您最终需要groupedMap
中已有的内容,因为进一步处理可能会导致重复键出错:
Map<String, String> newMap = groupedMap.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getValue,
Map.Entry::getKey));
{BC=2, AD=1}
可以,使用Collectors.collectingAndThen
(口味问题)将它们放在一起:
Map<String, String> newMap = map.entrySet().stream()
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(
Map.Entry::getKey,
Collectors.reducing("", (l, r) -> l + r))),
m -> m.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getValue,
Map.Entry::getKey))));
基于逻辑:
-
循环浏览地图
-
对于每个值,从新映射中获取相应的键(基于值)
-
如果新的映射键存在,请将其删除,然后在末尾加上额外的字母重新放置
-
如果不存在,则不带任何串联即可放置它。
for (var entry : map.entrySet()) { String newMapKey = getKey(newMap, entry.getValue()); if (newMapKey != null) { newMap.remove(newMapKey); newMap.put(newMapKey + entry.getKey(), entry.getValue()); continue; } newMap.put(entry.getKey(), entry.getValue()); }
额外的方法:
private static String getKey(HashMap<String, String> map, String value)
{
for (String key : map.keySet())
if (value.equals(map.get(key)))
return key;
return null;
}
{BC=2, AD=1}
使用 Java 8
您可以尝试以下方法以获得所需的结果。
法典:
public class Test {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
Map<String, String> newMap;
map.put("A","1");
map.put("B","2");
map.put("C","2");
map.put("D","1");
Map<String, String> tempMap = map.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey,Collectors.joining(""))));
newMap = tempMap.entrySet().stream().sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey,(a,b) -> a, LinkedHashMap::new));
System.out.println(newMap);
}
}
输出:
{AD=1, BC=2}
如果您希望源映射的键按字母顺序连接,如示例"AD"
、"BC"
(而不是"DA"
或"CB"
),那么您可以通过创建类型为Map<String,List<String>>
的中间映射并将源映射中的每个不同值与List
键相关联来确保这一点。然后对每个列表进行排序并从中生成一个字符串。
那如何实现:
Map<String, String> map = Map.of(
"A", "1", "B", "2","C", "2","D", "1"
);
Map<String, String> newMap = map.entrySet().stream()
.collect(Collectors.groupingBy( // intermediate Map<String, List<String>>
Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toList())
))
.entrySet().stream()
.collect(Collectors.toMap(
e -> e.getValue().stream().sorted().collect(Collectors.joining()),
Map.Entry::getKey
));
newMap.forEach((k, v) -> System.out.println(k + " -> " + v));
输出:
BC -> 2
AD -> 1