Java 如何对自定义比较器进行编码以对已分类的地图进行排序?
我是Java新手,正在学习集合。作为练习,我尝试使用自定义比较器对SortedMap进行排序。我希望能够按照平均成绩按降序对学生进行分类Java 如何对自定义比较器进行编码以对已分类的地图进行排序?,java,Java,我是Java新手,正在学习集合。作为练习,我尝试使用自定义比较器对SortedMap进行排序。我希望能够按照平均成绩按降序对学生进行分类 SortedMap students=newtreemap() 公共班级学生{ 私有字符串名称; 私有列表标记=新的ArrayList(); 公立学生(字符串n){ this.name=n; } 公共字符串getName(){ 返回此.name; } 公共双getAvg(){ 返回这个。getStats() .getAverage(); } 公共无效添加标记(
SortedMap students=newtreemap()代码>
公共班级学生{
私有字符串名称;
私有列表标记=新的ArrayList();
公立学生(字符串n){
this.name=n;
}
公共字符串getName(){
返回此.name;
}
公共双getAvg(){
返回这个。getStats()
.getAverage();
}
公共无效添加标记(整数标记){
此.marks.add(标记);
}
公共DoubleSummaryStatistics getStats(){
返回此.marks.stream()
.mapToDouble(标记->标记)
.summaryStatistics();
}
@凌驾
公共字符串toString(){
返回此.name+“”+getStats().getCount()+“”+getStats().getAverage();
}
}
我能够想出如何构建一个返回集合的自定义比较器:
SortedSet<Map.Entry<String, Student>> meritSet = new TreeSet<Map.Entry<String, Student>>(
new Comparator<Map.Entry<String, Student>>() {
@Override
public int compare(Map.Entry<String, Student> s1,
Map.Entry<String, Student> s2) {
Double s1Avg = students.get(s1.getKey()).getStats().getAverage();
Double s2Avg = students.get(s2.getKey()).getStats().getAverage();
return s1Avg.compareTo(s2Avg);
}
}
);
meritSet.addAll(students.entrySet());
SortedSet meritSet=新树集(
新比较器(){
@凌驾
公共整数比较(映射项s1,
地图输入(s2){
Double s1Avg=students.get(s1.getKey()).getStats().getAverage();
Double s2Avg=students.get(s2.getKey()).getStats().getAverage();
返回s1Avg.compareTo(s2Avg);
}
}
);
addAll(students.entrySet());
如何对返回SortedMap而不是SortedSet的自定义比较器进行编码?您要做的是根据其值对映射进行排序。
然而,这并不是一个简单的方法可以实现的
进一步提供其键的总顺序的映射
如果您只想在Map
中存储已排序的条目,而不需要在添加新值时仍对Map
进行排序,则可以将所有条目存储在:
Map meritMap=meritSet.stream()
.collect(toMap(Map.Entry::getKey,Map.Entry::getValue,(a,b)->a,LinkedHashMap::new));
虽然这不会给您一个SortedMap
,但是Map
会被排序。您要做的是根据它的值对Map
进行排序。
然而,这并不是一个简单的方法可以实现的
进一步提供其键的总顺序的映射
如果您只想在Map
中存储已排序的条目,而不需要在添加新值时仍对Map
进行排序,则可以将所有条目存储在:
Map meritMap=meritSet.stream()
.collect(toMap(Map.Entry::getKey,Map.Entry::getValue,(a,b)->a,LinkedHashMap::new));
虽然这不会给你一个SortedMap
,但是Map
会被排序。为了使用实现SortedMap的树状图你能做的是让学生实现类似的:
public class Student implements Comparable<Student> {
/*
* nearly the entire class stays untouched,
* except from the class declaration and the additional method below
*/
@Override
public int compareTo(Student o) {
return this.getAvg().compareTo(o.getAvg());
}
// you could and probably should implement equals(Student o) and hashCode() as well
}
公共班级学生实施可比{
/*
*几乎整个班级都没有受到影响,
*除了类声明和下面的附加方法之外
*/
@凌驾
公共内部比较(学生o){
返回这个.getAvg().compareTo(o.getAvg());
}
//您可能也应该实现equals(Student o)和hashCode()
}
这将根据方法getAvg()
(使用Double的方法compareTo
)的值自动对TreeMap
中的条目进行排序
TreeMap
将按其键排序。。。因此,请考虑使用<代码> map < /代码>,以<代码>学生<代码> s为关键字。
如果您现在想要一个分类集
,比如树集
,它将被相应地排序,只需实现可比
,为了使用实现分类映射的树映射
,您可以做什么
public class Student implements Comparable<Student> {
/*
* nearly the entire class stays untouched,
* except from the class declaration and the additional method below
*/
@Override
public int compareTo(Student o) {
return this.getAvg().compareTo(o.getAvg());
}
// you could and probably should implement equals(Student o) and hashCode() as well
}
公共班级学生实施可比{
/*
*几乎整个班级都没有受到影响,
*除了类声明和下面的附加方法之外
*/
@凌驾
公共内部比较(学生o){
返回这个.getAvg().compareTo(o.getAvg());
}
//您可能也应该实现equals(Student o)和hashCode()
}
这将根据方法getAvg()
(使用Double的方法compareTo
)的值自动对TreeMap
中的条目进行排序
TreeMap
将按其键排序。。。因此,请考虑使用<代码> map < /代码>,以<代码>学生<代码> s为关键字。
如果您现在想要有一个排序集
,比如树集
,它将被相应地排序,只要实现了可比
,这是否回答了您的问题<代码>分类地图
不符合您的要求。它基于键进行排序
,您的需求基于值
。也许考虑两张地图。一个带有String
键,另一个带有Student
askeys@Ward当然有帮助,谢谢。这能回答你的问题吗<代码>分类地图
不符合您的要求。它基于键进行排序
,您的需求基于值
。也许考虑两张地图。一个带有String
键,另一个带有Student
askeys@Ward当然有帮助,谢谢。
public class Student implements Comparable<Student> {
/*
* nearly the entire class stays untouched,
* except from the class declaration and the additional method below
*/
@Override
public int compareTo(Student o) {
return this.getAvg().compareTo(o.getAvg());
}
// you could and probably should implement equals(Student o) and hashCode() as well
}