A map is basically an unsorted collection but there are sorted maps as well, e.g. TreeMap
. In that case provide a comparator which sorts projects based on their to the constructor:
SortedMap<Project, List<Activity>> myMap = new TreeMap<>( new Comparator<Project>() {
public int compare( Project lhs, Project rhs) {
int r = lhs.unit.unitName.compareTo(rhs.unit.unitName); //note that null checks etc. are omitted for simplicity, don't forget them in your code unless you know for sure that unit and unitName can't be null
if( r == 0 && !lhs.equals(rhs)) {
//take other properties into account for consistent behavior with equals()
//see "Update 2" below
}
return r;
}
});
Note that if you need to sort the map using a different comparator (or can't provide a comparator) you'd have to create a list using the entries of the map and sort that.
Something like this:
List<Map.Entry<Project, List<Activity>> l = new ArrayList<>(myMap.entrySet());
Collections.sort(l, new Comparator<Map.Entry<Project, List<Activity>>() {
public int compare( Map.Entry<Project, List<Activity> lhs, Map.Entry<Project, List<Activity> rhs) {
return lhs.getKey().unit.unitName.compareTo(rhs.getKey().unit.unitName);
}
});
Also note that it is not possible for a collection or sorted map to have different sort orders, i.e. you can only provide one comparator or natural ordering for the elements.
In any case you'd either have to change the sort order of the collection (e.g. by using Collections.sort(...)
or, if you need to maintain multiple orders simultanously, use multiple collections (which can be sorted views to a base collection/map).
Update I'll add an example for a copy of the TreeMap
:
//new TreeMap like above
SortedMap<Project, List<Activity>> copy = new TreeMap<>( new Comparator<Project>() { ... } );
copy.putAll( myMap );
Update 2
As for the comparator, note that it is required to be consistent with equals, i.e. the comparator must only return 0 if both objects are equal. Thus you'd need to take other properties of a Project
into account if the units are equal. Without that, if two projects use the same unit, they are considered equal by the TreeMap
and thus entries might get lost.
For more information see: What does comparison being consistent with equals mean ? What can possibly happen if my class doesn't follow this principle?
The compare method might look like this, if the project names are unique:
public int compare( Project lhs, Project rhs) {
//as above null checks etc. are omitted for simplicity's sake
int r = lhs.unit.unitName.compareTo(rhs.unit.unitName);
if( r == 0 && !lhs.equals(rhs)) {
r = lhs.projectName.compareTo( rhs.projectName );
//you could also use the natural ordering of the projects here:
//r = lhs.compareTo( rhs );
}
return r;
}