Mohammad Shahadat Hossain Mohammad Shahadat Hossain - 27 days ago 7
Java Question

Sort Map elements in java Map<String, List<String>> in reverseorder

In my java program, i am getting result like

Output:


acre care race

act cat


Expected:


act cat

acre care race


Now I want to sort the Map elements in reverse order. So I can get the result like above. I added my code in below.

public static void main(String args[]) {

try {
Scanner sc = readWords();
Map<String, List<String>> wordAnagramPairs = new HashMap<>();
wordAnagramPairs = mapAnagrams(sc);
Comparator<List<String>> c = (l1, l2) -> {
Collections.sort(l1);
Collections.sort(l2);
int in = l1.get(0).length() - l2.get(0).length();
if (in == 0) {
return String.join(" ", l1).compareTo(String.join(" ", l2));
} else {
return in;
}
};
List<List<String>> sortedList = wordAnagramPairs.values()
.stream()
.filter(li -> li != null && li.size() > 1)
.sorted(c)
.collect(Collectors.toList());

for(List<String> anagrams : sortedList){
for(String anagram : anagrams){
System.out.print(anagram + " ");
}
System.out.print('\n');
}

} catch (FileNotFoundException e) {
System.out.println("File Not Found");
}
}

Answer

By looking at your expected output, it seems you need to sort by length of the list element and then by the sorted list elements if the length is equal

To compare by element length and then list elements

Comparator<List<String>> c = (l1, l2) -> {
            Collections.sort(l1); // elements to be sorted
            Collections.sort(l2); // elements to be sorted
            int in = l1.get(0).length() - l2.get(0).length();
            if (in == 0) {
                return String.join(" ", l1).compareTo(String.join(" ", l2));
            } else {
                return in;
            }
        };

Since you want only the values to be printed you can use stream on values

    Map<String, List<String>> wordAnagramPairs = new HashMap<>();
    wordAnagramPairs.put("race", Arrays.asList("race", "care", "acre"));
    wordAnagramPairs.put("act", Arrays.asList("act", "cat"));
    wordAnagramPairs.values().stream()
                             .filter(li -> li != null && li.size() > 1)
                             .sorted(c)
                             .forEach(System.out::println);

Output

[act, cat]
[acre, care, race]

To collect the sorted results

    List<List<String>> sortedList = wordAnagramPairs.values().stream().filter(li -> li != null && li.size() > 1).sorted(c)
            .collect(Collectors.toList());

    System.out.println(sortedList);

You can also use TreeMap<String, TreeSet<String>> to sort the map by key and sort the values by Set value

To sort by key

    wordAnagramPairs.entrySet()
                    .stream()
                    .filter(e -> e.getValue().size() > 1)
                    .sorted(Map.Entry.comparingByKey())
                    .forEach(System.out::println);