假设我们有一个名为 Activity 的类:
public class Activity {
private Project project;
}
所以每个 Activity 对象都会有一个项目..而且每个项目都有一个单元。两个不同的项目可以具有相同的单位:
public class Project {
private String projectName;
private Unit unit;
}
一个单位也有一个名称:
public class Unit {
private String unitName;
}
所以目前我有一个像这样的 TreeMap:
SortedMap<Project,List<Activity> myMap
一个例子可能是:
projectOne -> [activityOne,activityTwo,activityThree]
projectTwo -> [activityThree,activityFouractivityFive]
projectThree -> [activityFour,activityFive,activitySix]
等等...
现在假设projectOne 与projectThree 具有相同的单位(unitAAA),projectTwo 具有unitZZZ...
我想按项目元素的单位按字母顺序对 map 进行排序:
projectOne -> [...]
projectThree -> [...]
projectTwo -> [...]
我怎样才能实现这个目标?我知道 Stackoverflow 中的问题是到目前为止你尝试过什么?,好吧,我真的陷入了这一点,所以除了尝试想出我可以尝试的东西之外,我还没有真正尝试过任何东西。
最佳答案
map 基本上是一个未排序的集合,但也有排序的 map ,例如树形图
。在这种情况下,提供一个比较器,根据构造函数对项目进行排序:
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;
}
});
请注意,如果您需要使用不同的比较器对 map 进行排序(或无法提供比较器),则必须使用 map 的条目创建一个列表并对其进行排序。
类似这样的事情:
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(...)
,或者,如果您需要同时维护多个顺序,请使用多个集合(可以将 View 排序到基本集合/ map )。
更新我将添加一个 TreeMap
副本的示例:
//new TreeMap like above
SortedMap<Project, List<Activity>> copy = new TreeMap<>( new Comparator<Project>() { ... } );
copy.putAll( myMap );
更新2
对于比较器,请注意,它需要与 equals 一致,即如果两个对象相等,则比较器只能返回 0。因此,如果单位相等,您需要考虑 Project
的其他属性。如果没有这个,如果两个项目使用相同的单元,TreeMap
会认为它们是相等的,因此条目可能会丢失。
如果项目名称是唯一的,则比较方法可能如下所示:
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;
}
关于java - 如何根据映射中键的某些属性对映射进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22171082/