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");
Expected Output: "AD", "1" and "BC", "2" present inside the newMap which means, if the data values were same it needs combine its keys to have only one data value by combining its keys inside the newMap created how to achieve this in Java?
CodePudding user response:
You want to group by the "integer" value using Collectors.groupingBy
and collect the former keys as a new value. By default, grouping yields in List
. You can further use downstream collector Collectors.mapping
and another downstream collector Collectors.reducing
to map and concatenate the individual items (values) as a single String.
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}
Now, you can switch keys with values for the final result:
Map<String, String> newMap = groupedMap.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getValue,
Map.Entry::getKey));
{BC=2, AD=1}
It is possible, put it all together using Collectors.collectingAndThen
(matter of taste):
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))));
CodePudding user response:
Based on logic:
Loop through your map
For each value, get the corresponding key from the new map (based on the value)
If the new map key exists, remove it and put it again with the extra letter at the end
If not exists, just put it without any concatenation.
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()); }
The extra method:
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}
CodePudding user response:
Using Java 8
You can try the below approach in order to get the desired result.
Code:
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);
}
}
Output:
{AD=1, BC=2}