Lozar2605
Lozar2605

Reputation: 3

Sorting LinkedHashMap<String, ArrayList<String>> by counting the occurrences in ArrayList<String> problem

I have:

ArrayList<String> miss;
LinkedHashMap<String, ArrayList<String>> map;

How can i sort "maps" by counting the occurrences in "miss"? For example:

  1. miss => [3, 7]
  2. 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]}

Upvotes: 0

Views: 104

Answers (1)

Nowhere Man
Nowhere Man

Reputation: 19565

The following solution is based on using Stream API

  1. Count the frequencies of elements from miss in each list value of maps and collect the frequency into some object (e.g. a list)
  2. 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)
  3. Build the resulting map using Collectors.toMap with LinkedHashMap::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]}

Upvotes: 1

Related Questions