使用覆盖 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前面,与 分数低的 排前面的排序规则相违背,所以发生错误。
   不知道这么想是否正确,请高手解惑。。谢谢 

解决方案 »

  1.   

    这种处理方式有问题,给你一个解决方案:
    添加一个辅助类:
    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里面去做求和运算~
    他能做的仅仅是把求和后的数据放进去,
    而前面的一个数据依旧存在里面~