Reputation: 329
I have the following Map:
Map<String, List<String>> map = new HashMap<String, List<String>>();
which is filled with pairs of keys and values.
For example: key = student name and value = family members names.
I want to sort the map by the size of the list of strings. I have tried implementing Comparator with a TreeMap but I got an error so I switched back to HashMap. Any ideas?
Upvotes: 3
Views: 7777
Reputation: 198103
The solution is more or less identical to https://stackoverflow.com/a/8897384/869736, but all you need to do is write a Comparator
that compares lists by their length.
Comparator<List<String>> lengthComparator = new Comparator<List<String>>() {
public int compare(List<String> a, List<String> b) {
return a.size() - b.size();
// size() is always nonnegative, so this won't have crazy overflow bugs
}
};
and then just use the solution outlined there.
Upvotes: 3
Reputation: 8582
You should use the HashMap unordered, and then each time you want to order, put all the values of the HashMap into a TreeMap, using a Comparator that has the HashMap as a variable.
Then, for each key you compare, you get the value of the HashMap (the list) and check the list size. So you compare by the list sizes, returning -1, 0 or 1 depending on the case.
Once you finish what you need, you discard that TreeMap.
If you try to use only a TreeMap, then you'll see that you are ordering the keys according to a value that is not a property of such key. In this case, the length of the value (a list). So, there may exist a function that increases the length of the list, and the TreeMap won't even notice.
Some code:
public class ListSizeComparator implements Comparator<String> {
private final Map<String, List<String>> map;
public ListSizeComparator(final Map<String, List<String>> map) {
this.map = map;
}
@Override
public int compare(String s1, String s2) {
//Here I assume both keys exist in the map.
List<String> list1 = this.map.get(s1);
List<String> list2 = this.map.get(s2);
Integer length1 = list1.size();
Integer length2 = list2.size();
return length1.compareTo(length2);
}
}
Upvotes: 3
Reputation: 2699
I see three choices here:
TreeMap<Integer, List<String>>
(key - number of family members, value - list of students).TreeMap<Integer, Map<String, List<String>>>
(key - number of family members, value - part of your original map containing students with number of family members equal $key).Upvotes: 0