/* TreeSet可以对Set集合中的对象进行排序; 原理,TreeSet在底层调用了Comparable接口的方法compareTo(). 所以,在使用TreeSet存储自定义对象时,要想实现自定义类对象的自然排序,需要类实现Comparable接口,并重写覆盖接口唯一的方法compareTo(). 需求: 往TreeSet集合中存储自定义对象学生。 想按照学生的年龄进行排序。 记住:排序时,当主要条件相同时,一定判断一下次要条件。 在本例中,出现了两个同学的年龄是一样的,如果不进行判断次要条件动作,那么会有的学生的信息存储不上,应为在compareTo时返回的是0. 所以,需要继续判断姓名是否一致。在String类中也实现了Comparable接口中的compareTo方法。所以可以直接使用str.compareTo(str1)来实现字符串的比较。 TreeSet的底层数据结构是二叉树的。保存数据唯一性的依据是compareTo方法返回0. TreeSet排序的第一种方式:让元素自身具备比较性。 元素需要实现Comparable接口,覆盖compareTo方法。 这种方式也称为元素的自然顺序,或者叫做默认顺序。 TreeSet排序的第二种方式:元素本身不具备比较性,那就构造比较器,比较器作为参数传递给TreeSet含参的构造函数。 当两种方式都存在时,以比较器为主。 !!!!!!!!!!!!两种方式的实现在程序TreeSetDemo1.java中!!!!!!!!!!!!!!!!!! */ import java.util.*; class Student implements Comparable//因为TreeSet会对存的对象进行自然排序,其实是它实现了Comparable接口。 { private String name; private int age; Student(String name,int age) { this.name=name; this.age=age; } public String getName() { return name; } public int getAge() { return age; } public int compareTo(Object obj) //重写接口中的方法,实现按年龄进行排序的功能。 { if(!(obj instanceof Student)) throw new RuntimeException("不是学生对象"); Student s=(Student)obj; TreeSetDemo.sop(this.name+"......"+s.name); TreeSetDemo.sop(this.name); //首先是Lily_01进来并存储在TreeSet集合中。然后是Lily_02进来并与Lily_01进行比较。 if(this.age>s.age) //底层调用的是compareTo方法。所以在lily_02进来后,this值得就是Lily_02。说白了就是谁进来this就代表谁。 return 1; //大的放在二叉树的右边 if(this.age==s.age) { return this.name.compareTo(s.name); //如果说是一样的话,就不会存储相同的对象。 } return -1; //小的放在二叉树的左边。 } } class TreeSetDemo { public static void main(String[] args) { TreeSet ts=new TreeSet(); ts.add(new Student("Lily_01",10)); ts.add(new Student("Lily_02",9)); //ts.add(new Student("Lily_03",15)); //ts.add(new Student("Lily_04",18)); //ts.add(new Student("Lily_05",5)); //ts.add(new Student("Lily_06",18)); //ts.add(new Student("Lily_07",20)); Iterator it=ts.iterator(); while(it.hasNext()) { Object obj=it.next(); Student s=(Student)obj; //sop(s.getName()+".."+s.getAge()); } System.out.println("Hello World!"); } public static void sop(Object obj) { System.out.println(obj); } }
/* 总结,TreeSet可以对存入的对象进行自然顺序的排序, 是因为其底层数据结构是二叉树,并且实现了Comparable接口的compareTo()方法。 通过自定义对象的类实现Comparable接口,并覆盖compareTo()方法,即可根据自己的需要存储 有顺序的对象数据。 返回1,说明新进元素较大,放在二叉树的右子节点; 返回-1,说明新进元素较小,放在二叉树的左子节点; 返回0,说明对象元素一致,则再比较其他次要条件(比如姓名一样,就比较年龄) */ import java.util.*; class Student implements Comparable { private String name; private int age; Student(String name,int age) { this.name=name; this.age=age; } public String getName() { return name; } public int getAge() { return age; } public int compareTo(Object obj) { /*按照姓名进行排序,如果姓名一样,那就按照年龄进行排序(升序)*/ if(!(obj instanceof Student)) throw new RuntimeException("不是学生对象"); Student s=(Student)obj; int x=this.name.compareTo(s.name); if(x==0) { if(this.age>s.age) return 1; if(this.age==s.age) return 0; return -1; } return x; /* 按照输入的顺序输出: return 1; */ /* 按照输入的顺序逆序输出: return -1; */ /* 只存储一个学生的信息: return 0; */ } } class TreeSetDemo1 { public static void main(String[] args) { TreeSet ts=new TreeSet();//使用方式一:通过实现Comparable接口并覆盖其中的compareTo()方法. TreeSet ts=new TreeSet(new MyCompare()); //使用方式二:使用比较器对年龄进行排序。构造比较器实现Comparator接口,并覆盖compare方法。 ts.add(new Student("Lily",20)); ts.add(new Student("Jhon",30)); ts.add(new Student("Jane",19)); ts.add(new Student("Sara",17)); ts.add(new Student("Demetria",25)); ts.add(new Student("Mike",25)); ts.add(new Student("Lily",25)); Iterator it=ts.iterator(); while(it.hasNext()) { Student s=(Student)it.next(); sop(s.getName()+","+s.getAge()); } System.out.println("Hello World!"); } public static void sop(Object obj) { System.out.println(obj); } } class MyCompare implements Comparator //定义比较器,实现按照学生年龄进行排序 { public int compare(Object obj1,Object obj2) { if(!(obj1 instanceof Student)||!(obj2 instanceof Student)) throw new RuntimeException("有对象不是Student类型的。"); Student s1=(Student)obj1; Student s2=(Student)obj2; if(s1.getAge()>s2.getAge()) return 1; if(s1.getAge()==s2.getAge()) return s1.getName().compareTo(s2.getName()); return -1; } }