地图基本上是一个未排序的集合,但也有排序的地图,例如TreeMap。在这种情况下,提供一个比较器,它根据项目对构造函数进行排序:
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;
}
});
请注意,如果您需要使用不同的比较器(或无法提供比较器)对地图进行排序,则必须使用地图的条目创建一个列表并对其进行排序。
类似这样的:
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);
}
});
另请注意,集合或排序映射不可能有不同的排序顺序,即您只能为元素提供一个比较器或自然排序。
在任何情况下,您都必须更改集合的排序顺序(例如,通过使用 Collections.sort(...) 或者,如果您需要同时维护多个顺序,请使用多个集合(可以将视图排序到基础集合/地图)。
更新我将为TreeMap的副本添加一个示例:
//new TreeMap like above
SortedMap<Project, List<Activity>> copy = new TreeMap<>( new Comparator<Project>() { ... } );
copy.putAll( myMap );
更新 2
至于比较器,注意它必须与equals一致,即比较器必须只有在两个对象相等时才返回0。因此,如果单位相等,您需要考虑 Project 的其他属性。否则,如果两个项目使用相同的单位,TreeMap 会认为它们相等,因此条目可能会丢失。
欲了解更多信息,请参阅:What does comparison being consistent with equals mean ? What can possibly happen if my class doesn't follow this principle?
如果项目名称是唯一的,比较方法可能如下所示:
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;
}