I have:
ArrayList<String> miss; LinkedHashMap<String, ArrayList<String>> map;
How can i sort “maps” by counting the occurrences in “miss”? For example:
- miss => [3, 7]
- maps => {1=[0, 3, 6], 4=[2, 3, 4], 6=[0, 3, 7], 11=[1, 3, 6], 17=[2, 6, 11]}
And i want to get:
maps => {6=[0, 3, 7], 1=[0, 3, 6], 4=[2, 3, 4], 11=[1, 3, 6], 17=[2, 6, 11]}
Advertisement
Answer
The following solution is based on using Stream API
- Count the frequencies of elements from
miss
in each list value ofmaps
and collect the frequency into some object (e.g. a list) - Sort the new object by the frequency in the reverse order and then by the key of initial map (note: the key may need to be converted into int to provide the expected output: 1, 4, 11; comparing the keys as String returns the order 1, 11, 4)
- Build the resulting map using
Collectors.toMap
withLinkedHashMap::new
supplier
List<String> miss = List.of("3", "7"); Map<String, List<String>> maps = Map.of( "1", List.of("0", "3", "6"), "4", List.of("2", "3", "4"), "6", List.of("0", "3", "7"), "11", List.of("1", "3", "6"), "17", List.of("2", "6", "11") ); Map<String, List<String>> sorted = maps.entrySet() .stream() .map(e -> Arrays.asList(e, e.getValue().stream() .mapToInt(i -> (int) miss.stream().filter(i::equals).count()) .sum() )) .sorted(Comparator .<List>comparingInt(ee -> (int) ee.get(1)).reversed() .thenComparingInt(ee -> Integer.parseInt(((Map.Entry<String, List<String>>) ee.get(0)).getKey())) ) .map(ee -> (Map.Entry<String, List<String>>) ee.get(0)) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1, LinkedHashMap::new )); System.out.println(sorted);
Output:
{6=[0, 3, 7], 1=[0, 3, 6], 4=[2, 3, 4], 11=[1, 3, 6], 17=[2, 6, 11]}