自然排序Comparable
自然排序,就是让TreeSet元素所属的类实现Comparable接口,内部重写CompareTo()方法。
本文基于笔者自己创建的Student类,想要达成的效果是:
年龄从小到大排序,如果年龄相同,依照名字字母顺序排序。
下面是代码:
public class Studentpls implements Comparable{ private String name; private int age; public Studentpls(int age,String name) { this.age = age; this.name = name; } public void SetName(String name) { this.name = name; } public void SetAge(int age) { this.age = age; } public String GetName() { return this.name; } public int GetAge() { return this.age; } public void ShowName() { System.out.println(this.name); } public void ShowAge() { System.out.println(this.age); } //使用自然排序(implements Comparable)后必须重写compareTo方法 @Override public int compareTo(Studentpls s) { int num = this.age - s.age; int num2 = (num==0)?(this.name.compareTo(s.name)):(num); return num2; }}
注意点:
(1)自然排序在元素实例对应的类内实现,该类需要implements Comparable < E >
(2)重写的compareTo方法返回值规则:
return 0; 返回0,认为元素重复,不添加
return +1; 返回正数,升序排列
return -1; 返回负数
测试主函数:
public static void main(String[] args) { //创建TreeSet对象 TreeSet ts = new TreeSet(); //创建学生对象 Studentpls stu_1 = new Studentpls(25,"Jack"); Studentpls stu_2 = new Studentpls(30,"Tim"); //test3、test4对照 Studentpls stu_3 = new Studentpls(10,"Dick"); Studentpls stu_4 = new Studentpls(45,"Sam"); Studentpls stu_5 = new Studentpls(29,"Newton"); //test1对照 Studentpls stu_6 = new Studentpls(29,"Jim"); //test1:年龄同,名字不同 Studentpls stu_7 = new Studentpls(25,"Jack"); //test2:完全相同的数据 Studentpls stu_8 = new Studentpls(30,"Tony"); //test3:年龄同,首字母同 Studentpls stu_9 = new Studentpls(30,"Timy"); //test4:年龄同,名字多一个字母 //添加到集合中 ts.add(stu_1); ts.add(stu_2); ts.add(stu_3); ts.add(stu_4); ts.add(stu_5); ts.add(stu_6); ts.add(stu_7); ts.add(stu_8); ts.add(stu_9); //遍历 for(Studentpls s : ts) { System.out.println("名字:"+s.GetName()+" 年龄:"+s.GetAge()); } }
比较器排序Comparator
比较器排序,就是让集合构造方法接收Comparator的实现类对象(一般写成匿名内部类),重写compare(T o1,T o2)方法。
核心代码:
TreeSet ts = new TreeSet(new Comparator() { @Override public int compare(Student s1, Student s2) { int num = s1.GetAge() - s2.GetAge(); int num2 = (num==0) ? (s1.GetName().compareTo(s2.GetName())) : (num); return num2; } });
值得注意的是:此处有参构造传入的是一个匿名内部类,相当于传入一个使用这个类的匿名实例。整个匿名内部类被写在构造方法的括号中:
另外,使用比较器排序是在主函数内部进行重写的,不需要再元素对应类中重写,因而更多人倾向于使用比较器排序。
测试代码同上,不再赘述。
测试结果应该是: