前言:TreeSet集合是Set集合的一个子实现类,它是基于TreeMap中的NavigableSet接口实现的,TreeSet集合是默认经过天然排序将集合中的元素进行排序java
TreeSet有两种排序方式:面试
1)天然排序api
2)比较器排序(定制排序)dom
当定制排序和天然排序同时存在时,最终的排序结果是按照 定制排序 来的。ide
面试题:Comparable 和Comparator的区别:工具
① Comparable 天然排序 ,实体类实现Comparable接口,能够去重写compareTo()方法,解决实际排序问题。 把元素放到TreeSet里面去,就会自动的调用CompareTo方法; 可是这个Comparable并非专为TreeSet设计的;只是说TreeSet顺便利用而已; 就像haashCode和equals 也同样,不是说专门为HashSet设计同样;只是你顺便利用而已;this
② Compartor第三方的比较器接口,也不是专门为TreeSet设计。 用法:设计一个比较器. 建立一个类,实现这个接口,覆写compare()方法,解决不一样问题的需求。spa
1. 天然排序:设计
在TreeSet中默认要求里面的元素进行天然排序,强制要求里面的全部元素必须按照Comparable中的compareTo方法进行比较。code
若是容器里面的对象(好比:new Student(参数)对象)不具有compareTo方法此时就会抛出异常报错(ClassCastException),因此必需要让容器中的元素实现Comparable接口,这样它才具有compareTo方法。
1.TreeSet实例在调用add方法时会调用容器对象的compareTo方法对元素进行比较
2.TreeSet实例中对象必须是实现了Comparable接口
例如:比较Student学生类,应该从哪些方法进行比较?
通常从字段的方面进行比较;好比按照年龄比较;当年龄相等返回0,大于返回1,小于返回-1
姓名是字符串,怎样比较大小,查看api的时候,String已经实现了Comparable接口,String 类里面已经确定覆写Comparable方法,那是按照String的规则进行比较。
能够直接无论具体内 部是怎样比较,直接调用String类里面比较方法就能够.
package TreeSet; public class Student implements Comparable { private int age; private String name; public Student(){} public Student(int age,String name){ this.age = age; this.name = name; } @Override public int compareTo(Object obj) { //好比按照年龄比较;当年龄相等返回0,大于返回1,小于返回-1 Student stu = (Student)obj; if(this.age > stu.age){ return 1; }else if(this.age<stu.age){ return -1; }else{ return this.name.compareTo(stu.name); } } @Override public String toString() { return "<" + age + ", " + name + ">"; } }
public class TestStudent { public static void main(String[] args) { TreeSet set = new TreeSet(); set.add(new Student(20, "zs")); set.add(new Student(21, "zs")); set.add(new Student(22, "ww")); set.add(new Student(23, "zl")); System.out.println(set); } } //结果:[<20, zs>, <21, zs>, <22, ww>, <23, zl>]
2)比较器排序 建立TreeSet时,向其中传入已经重写Comparator中方法的对象
下面经过一个案例了解定制排序:
题目: 某班30个学生的学号为20070301-20070330,所有选修了Java程序设计课程,给出全部同窗的成绩(可用随机数产生,范围60-100),
请编写程序将本班各位同窗的成绩按照从低到高排序打印输出。
要求:1.分别用List、Set来实现,打印的信息包括学号、姓名和成绩。
2.用迭代器遍历
public class Student { private String name; private int id; private int score; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public Student(){} public Student(String name, int id, int score) { super(); this.name = name; this.id = id; this.score = score; } @Override public String toString() { return "学生 [姓名=" + name + ", 学号=" + id + ", 成绩=" + score + "]"; }
import java.util.Comparator; public class myComparator implements Comparator{ @Override public int compare(Object o1, Object o2) { Student s1 = (Student)o1; Student s2 = (Student)o2; if(s1.getScore()>s2.getScore()){ return 1; }else if(s1.getScore()<s2.getScore()){ return -1; }else{ return s1.getName().compareTo(s2.getName()); } } }
package 学生成绩排序题目; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.TreeSet; public class Test { public static void main(String[] args) { //使用list集合+定制排序+迭代器遍历(注意list.sort(), list不支持天然排序) List list = new ArrayList(); for(int i =20070301;i<=20070330;i++){ Student s = new Student("代号$"+(i-20070300),i,(int)(Math.random()*41+60)); list.add(s); } /* //这里涉及list集合排序的两种方法 list.sort(new myComparator()); //这里介绍Collections工具类的sort()方法: //参数不一样: 1. void sort(List list),按天然排序的升序排序 // 2. void sort(List list, Comparator c);定制排序,由Comparator控制排序逻辑 // 1. Collections.sort(list); //这里因为Student类中没有实现天然排序,因此直接调用会报类型转换异常 ClassCastException // 2. Collections.sort(list,new myComparator()); //能够正常排序 Iterator it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } */ //使用TreeSet集合+定制排序+迭代器遍历,并统计个数(也可使用treeSet的天然排序) TreeSet set = new TreeSet(new myComparator()); for(int i =20070301;i<=20070330;i++){ Student s = new Student("代号$"+(i-20070300),i,(int)(Math.random()*41+60)); set.add(s); } Iterator it = set.iterator(); int count = 0; while(it.hasNext()){ count++; System.out.println(count); System.out.println(it.next()); } } }
结果: 1 学生 [姓名=代号$10, 学号=20070310, 成绩=60] 2 学生 [姓名=代号$12, 学号=20070312, 成绩=60] 3 学生 [姓名=代号$26, 学号=20070326, 成绩=60] 4 学生 [姓名=代号$1, 学号=20070301, 成绩=61] 5 学生 [姓名=代号$28, 学号=20070328, 成绩=65] 6 学生 [姓名=代号$21, 学号=20070321, 成绩=69] 7 学生 [姓名=代号$11, 学号=20070311, 成绩=71] 8 学生 [姓名=代号$24, 学号=20070324, 成绩=71] 9 学生 [姓名=代号$16, 学号=20070316, 成绩=72] 10 学生 [姓名=代号$5, 学号=20070305, 成绩=72] 11 学生 [姓名=代号$9, 学号=20070309, 成绩=73] 12 学生 [姓名=代号$2, 学号=20070302, 成绩=74] 13 学生 [姓名=代号$3, 学号=20070303, 成绩=74] 14 学生 [姓名=代号$20, 学号=20070320, 成绩=76] 15 学生 [姓名=代号$6, 学号=20070306, 成绩=78] 16 学生 [姓名=代号$14, 学号=20070314, 成绩=79] 17 学生 [姓名=代号$29, 学号=20070329, 成绩=79] 18 学生 [姓名=代号$7, 学号=20070307, 成绩=79] 19 学生 [姓名=代号$18, 学号=20070318, 成绩=80] 20 学生 [姓名=代号$17, 学号=20070317, 成绩=83] 21 学生 [姓名=代号$25, 学号=20070325, 成绩=87] 22 学生 [姓名=代号$13, 学号=20070313, 成绩=88] 23 学生 [姓名=代号$15, 学号=20070315, 成绩=89] 24 学生 [姓名=代号$30, 学号=20070330, 成绩=89] 25 学生 [姓名=代号$8, 学号=20070308, 成绩=90] 26 学生 [姓名=代号$23, 学号=20070323, 成绩=92] 27 学生 [姓名=代号$19, 学号=20070319, 成绩=93] 28 学生 [姓名=代号$27, 学号=20070327, 成绩=93] 29 学生 [姓名=代号$4, 学号=20070304, 成绩=93] 30 学生 [姓名=代号$22, 学号=20070322, 成绩=98]