1.排序的引入
由于TreeSet可以实现对元素按照某种规则进行排序,例如下面的例子
1 public class TreeSetDemo { 2 public static void main(String[] args) { 3 // 创建集合对象 4 // 自然顺序进行排序 5 TreeSet<Integer> ts = new TreeSet<Integer>(); 6 7 // 创建元素并添加 8 // 20,18,23,22,17,24,19,18,24 9 ts.add(20); 10 ts.add(18); 11 ts.add(23); 12 ts.add(22); 13 ts.add(17); 14 ts.add(24); 15 ts.add(19); 16 ts.add(18); 17 ts.add(24); 18 19 // 遍历 20 for (Integer i : ts) { 21 System.out.println(i); 22 } 23 } 24 }
运行结果为:
但是对自定义对象呢?
1 public class TreeSetDemo02 { 2 public static void main(String[] args) { 3 TreeSet<Student> ts=new TreeSet<Student>(); 4 //创建元素对象 5 Student s1=new Student("zhangsan",20); 6 Student s2=new Student("lis",22); 7 Student s3=new Student("wangwu",24); 8 Student s4=new Student("chenliu",26); 9 Student s5=new Student("zhangsan",22); 10 Student s6=new Student("qianqi",24); 11 12 //将元素对象添加到集合对象中 13 ts.add(s1); 14 ts.add(s2); 15 ts.add(s3); 16 ts.add(s4); 17 ts.add(s5); 18 ts.add(s6); 19 20 //遍历 21 for(Student s:ts){ 22 System.out.println(s.getName()+"-----------"+s.getAge()); 23 } 24 } 25 }
Student类:
1 public class Student { 2 private String name; 3 private int age; 4 5 public Student() { 6 super(); 7 // TODO Auto-generated constructor stub 8 } 9 10 public Student(String name, int age) { 11 super(); 12 this.name = name; 13 this.age = age; 14 } 15 16 public String getName() { 17 return name; 18 } 19 20 public void setName(String name) { 21 this.name = name; 22 } 23 24 public int getAge() { 25 return age; 26 } 27 28 public void setAge(int age) { 29 this.age = age; 30 } 31 }
运行结果:
原因分析:
由于不知道该安照那一中排序方式排序,所以会报错。
解决方法:
1.自然排序
2.比较器排序
2.自然排序
自然排序要进行一下操作:
1.Student类中实现 Comparable<T>接口
2.重写Comparable接口中的Compareto方法
int |
compareTo(T o) 比较此对象与指定对象的顺序。 |
故Student类为:特别注意在重写Compareto方法时,注意排序
1 package xfcy_04; 2 /** 3 * Student类 4 * @author 晓风残月 5 * 6 */ 7 public class Student implements Comparable<Student> { 8 private String name; 9 private int age; 10 11 public Student() { 12 super(); 13 // TODO Auto-generated constructor stub 14 } 15 16 public Student(String name, int age) { 17 super(); 18 this.name = name; 19 this.age = age; 20 } 21 22 public String getName() { 23 return name; 24 } 25 26 public void setName(String name) { 27 this.name = name; 28 } 29 30 public int getAge() { 31 return age; 32 } 33 34 public void setAge(int age) { 35 this.age = age; 36 } 37 38 @Override 39 public int compareTo(Student s) { 40 //return -1; //-1表示放在红黑树的左边,即逆序输出 41 //return 1; //1表示放在红黑树的右边,即顺序输出 42 //return o; //表示元素相同,仅存放第一个元素 43 //主要条件 姓名的长度,如果姓名长度小的就放在左子树,否则放在右子树 44 int num=this.name.length()-s.name.length(); 45 //姓名的长度相同,不代表内容相同,如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。 46 //如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。 47 //如果这两个字符串相等,则结果为 0 48 int num1=num==0?this.name.compareTo(s.name):num; 49 //姓名的长度和内容相同,不代表年龄相同,所以还要判断年龄 50 int num2=num1==0?this.age-s.age:num1; 51 return num2; 52 } 53 54 }
而主类中为:
1 package xfcy_04; 2 3 import java.util.TreeSet; 4 5 /* 6 * TreeSet存储自定义对象并保证排序和唯一。 7 * 8 * 需求:请按照姓名的长度排序 9 */ 10 public class TreeSetDemo02 { 11 public static void main(String[] args) { 12 //创建集合对象 13 TreeSet<Student> ts=new TreeSet<Student>(); 14 15 16 //创建元素对象 17 Student s1=new Student("zhangsan",20); 18 Student s2=new Student("lis",22); 19 Student s3=new Student("wangwu",24); 20 Student s4=new Student("chenliu",26); 21 Student s5=new Student("zhangsan",22); 22 Student s6=new Student("qianqi",24); 23 24 //将元素对象添加到集合对象中 25 ts.add(s1); 26 ts.add(s2); 27 ts.add(s3); 28 ts.add(s4); 29 ts.add(s5); 30 ts.add(s6); 31 32 //遍历 33 for(Student s:ts){ 34 System.out.println(s.getName()+"-----------"+s.getAge()); 35 } 36 } 37 }
运行结果:
3、比较器排序
比较器排序步骤:
1.单独创建一个比较类,这里以MyComparator为例,并且要让其继承Comparator<T>接口
2.重写Comparator接口中的Compare方法
3.在主类中使用下面的 构造方法
TreeSet(Comparator<? superE> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。 |
主类:
1 package xfcy_04; 2 3 import java.util.TreeSet; 4 5 /* 6 * TreeSet存储自定义对象并保证排序和唯一。 7 * 8 * 需求:请按照姓名的长度排序 9 */ 10 public class TreeSetDemo02 { 11 public static void main(String[] args) { 12 //创建集合对象 13 //TreeSet(Comparator<? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。 14 TreeSet<Student> ts=new TreeSet<Student>(new MyComparator()); 15 16 //创建元素对象 17 Student s1=new Student("zhangsan",20); 18 Student s2=new Student("lis",22); 19 Student s3=new Student("wangwu",24); 20 Student s4=new Student("chenliu",26); 21 Student s5=new Student("zhangsan",22); 22 Student s6=new Student("qianqi",24); 23 24 //将元素对象添加到集合对象中 25 ts.add(s1); 26 ts.add(s2); 27 ts.add(s3); 28 ts.add(s4); 29 ts.add(s5); 30 ts.add(s6); 31 32 //遍历 33 for(Student s:ts){ 34 System.out.println(s.getName()+"-----------"+s.getAge()); 35 } 36 } 37 }
MyComparator类:
1 package xfcy_04; 2 3 import java.util.Comparator; 4 5 public class MyComparator implements Comparator<Student>{ 6 7 @Override 8 public int compare(Student s1,Student s2) { 9 // 姓名长度 10 int num = s1.getName().length() - s2.getName().length(); 11 // 姓名内容 12 int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; 13 // 年龄 14 int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2; 15 return num3; 16 } 17 18 19 20 21 }
学生类(不需要继承Comparetable接口)
1 package xfcy_04; 2 /** 3 * Student类 4 * @author 晓风残月 5 * 6 */ 7 public class Student{ 8 private String name; 9 private int age; 10 11 public Student() { 12 super(); 13 // TODO Auto-generated constructor stub 14 } 15 16 public Student(String name, int age) { 17 super(); 18 this.name = name; 19 this.age = age; 20 } 21 22 public String getName() { 23 return name; 24 } 25 26 public void setName(String name) { 27 this.name = name; 28 } 29 30 public int getAge() { 31 return age; 32 } 33 34 public void setAge(int age) { 35 this.age = age; 36 } 37 38 }
运行结果:
4.比较器修改(代码精简)
由于单独创建一个类不是特别好,因而可以将MyComparetor的内容直接写到主类中
1 public class TreeSetDemo { 2 public static void main(String[] args) { 3 // 如果一个方法的参数是接口,那么真正要的是接口的实现类的对象 4 // 而匿名内部类就可以实现这个东西 5 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { 6 @Override 7 public int compare(Student s1, Student s2) { 8 // 姓名长度 9 int num = s1.getName().length() - s2.getName().length(); 10 // 姓名内容 11 int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) 12 : num; 13 // 年龄 14 int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2; 15 return num3; 16 } 17 }); 18 19 // 创建元素 20 Student s1 = new Student("linqingxia", 27); 21 Student s2 = new Student("zhangguorong", 29); 22 Student s3 = new Student("wanglihong", 23); 23 Student s4 = new Student("linqingxia", 27); 24 Student s5 = new Student("liushishi", 22); 25 Student s6 = new Student("wuqilong", 40); 26 Student s7 = new Student("fengqingy", 22); 27 Student s8 = new Student("linqingxia", 29); 28 29 // 添加元素 30 ts.add(s1); 31 ts.add(s2); 32 ts.add(s3); 33 ts.add(s4); 34 ts.add(s5); 35 ts.add(s6); 36 ts.add(s7); 37 ts.add(s8); 38 39 // 遍历 40 for (Student s : ts) { 41 System.out.println(s.getName() + "---" + s.getAge()); 42 } 43 } 44 }
运行结果也如同上面一样
5.总结
A:自然排序:要在自定义类中实现Comparerable<T>接口 ,并且重写compareTo方法
B:比较器排序:在自定义类中实现Comparetor<t>接口,重写compare方法
----------天道酬勤----------------