使用覆盖 compareTo 排序,结果最后总会出现一个多余的数据,不知道为什么请教高手。package day11;import java.util.*;public class Try { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s1 = new Student("Huxz",97);
Student s2 = new Student("Huxz1",98);
Student s3 = new Student("Huxz",99);
Student s7 = new Student("Huxz1",97);
Student s8 = new Student("Huxz",98);
Student s9 = new Student("Huxz",99);
Student s4 = new Student("Liucy2",91);
Student s5 = new Student("Liucy",94);
Student s6 = new Student("Liucy2",95);
Set stu = new TreeSet();
stu.add(s1);
stu.add(s2);
stu.add(s3);
stu.add(s4);
stu.add(s5);
stu.add(s6);
stu.add(s7);
stu.add(s8);
stu.add(s9);
Iterator it = stu.iterator();
while(it.hasNext()){
Student s = (Student)it.next();
System.out.println(s);
}
}}
class Student implements Comparable{
public String name;
public int score;
public Student(String name,int score){
this.name = name;
this.score = score;
}
/**
* 排序规则 当两者姓名相同定义为同一人考了多门试,后者总分加前者后返回0
* 当两者姓名不同,成绩相同时,后输入者排名向上
* 成绩不同时,按总成绩高低排序
*/
public int compareTo(Object o){
Student s = (Student)o;
if(this.name.equals(s.name)){
//s.score += this.score;
return 0;
}
else if(this.score == s.score){
return -1;
}
else return this.score - s.score;
}
public String toString(){
return name+" "+score;
}
}
result : Huxz1 97
Liucy2 186
Liucy 94
Huxz 393
Huxz1 98本人的想法是 java 得 TreeSet 自动排序是针对新的输入元素的,即给新的输入元素找位置。但是当新的元素与旧的元素判定相同,覆盖后,却与compareto 的排序规则不兼容时就会发生错误。
即 A 60分 排在 B 70分前面,当新输入 A 90分 时,compareto 将旧的A 60 覆盖,那么此时 A 150 的位置为A 60的位置,排在B 70前面,与 分数低的 排前面的排序规则相违背,所以发生错误。
不知道这么想是否正确,请高手解惑。。谢谢
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s1 = new Student("Huxz",97);
Student s2 = new Student("Huxz1",98);
Student s3 = new Student("Huxz",99);
Student s7 = new Student("Huxz1",97);
Student s8 = new Student("Huxz",98);
Student s9 = new Student("Huxz",99);
Student s4 = new Student("Liucy2",91);
Student s5 = new Student("Liucy",94);
Student s6 = new Student("Liucy2",95);
Set stu = new TreeSet();
stu.add(s1);
stu.add(s2);
stu.add(s3);
stu.add(s4);
stu.add(s5);
stu.add(s6);
stu.add(s7);
stu.add(s8);
stu.add(s9);
Iterator it = stu.iterator();
while(it.hasNext()){
Student s = (Student)it.next();
System.out.println(s);
}
}}
class Student implements Comparable{
public String name;
public int score;
public Student(String name,int score){
this.name = name;
this.score = score;
}
/**
* 排序规则 当两者姓名相同定义为同一人考了多门试,后者总分加前者后返回0
* 当两者姓名不同,成绩相同时,后输入者排名向上
* 成绩不同时,按总成绩高低排序
*/
public int compareTo(Object o){
Student s = (Student)o;
if(this.name.equals(s.name)){
//s.score += this.score;
return 0;
}
else if(this.score == s.score){
return -1;
}
else return this.score - s.score;
}
public String toString(){
return name+" "+score;
}
}
result : Huxz1 97
Liucy2 186
Liucy 94
Huxz 393
Huxz1 98本人的想法是 java 得 TreeSet 自动排序是针对新的输入元素的,即给新的输入元素找位置。但是当新的元素与旧的元素判定相同,覆盖后,却与compareto 的排序规则不兼容时就会发生错误。
即 A 60分 排在 B 70分前面,当新输入 A 90分 时,compareto 将旧的A 60 覆盖,那么此时 A 150 的位置为A 60的位置,排在B 70前面,与 分数低的 排前面的排序规则相违背,所以发生错误。
不知道这么想是否正确,请高手解惑。。谢谢
添加一个辅助类:
class MySet{
Map<String, Student> m = new HashMap<String, Student>();
public void add(Student s) {
Student tmpS;
if (m.containsKey(s.getName())){
tmpS = m.get(s.getName());
tmpS.setScore(tmpS.getScore()+s.getScore());
}else{
tmpS = s;
}
m.put(s.getName(), tmpS);
}
public Set<Student> getSet(){
Set<Student> s = new TreeSet<Student>();
for(Entry<String, Student> entry : m.entrySet()){
s.add(entry.getValue());
}
return s;
}
}main方法里稍作改变:
public static void main(String[] args) {
Student s1 = new Student("Huxz", 97);
Student s2 = new Student("Huxz1", 98);
Student s3 = new Student("Huxz", 99);
Student s7 = new Student("Huxz1", 97);
Student s8 = new Student("Huxz", 98);
Student s9 = new Student("Huxz", 99);
Student s4 = new Student("Liucy2", 91);
Student s5 = new Student("Liucy", 94);
Student s6 = new Student("Liucy2", 95); MySet ms = new MySet();
ms.add(s1);
ms.add(s2);
ms.add(s3);
ms.add(s4);
ms.add(s5);
ms.add(s6);
ms.add(s7);
ms.add(s8);
ms.add(s9);
Set<Student> stu = ms.getSet();
for (Student s : stu) {
System.out.println(s);
}
}
其他地方都不用变~
输出结果
Liucy 94
Liucy2 186
Huxz1 195
Huxz 393辅助类的主要作用就是合并名字相同的分数~
在TreeSet里面可以做排序,
但是并不能改变已经保存到里面的数据,
因此不要希望在TreeSet里面去做求和运算~
他能做的仅仅是把求和后的数据放进去,
而前面的一个数据依旧存在里面~