TreeSet的两种排序方式

1.排序的引入

由于TreeSet可以实现对元素按照某种规则进行排序,例如下面的例子

[java] view plaincopyprint?
  1. public class TreeSetDemo {
  2. public static void main(String[] args) {
  3. // 创建集合对象
  4. // 自然顺序进行排序
  5. TreeSet<Integer> ts = new TreeSet<Integer>();
  6. // 创建元素并添加
  7. // 20,18,23,22,17,24,19,18,24
  8. ts.add(20);
  9. ts.add(18);
  10. ts.add(23);
  11. ts.add(22);
  12. ts.add(17);
  13. ts.add(24);
  14. ts.add(19);
  15. ts.add(18);
  16. ts.add(24);
  17. // 遍历
  18. for (Integer i : ts) {
  19. System.out.println(i);
  20. }
  21. }
  22. }
public class TreeSetDemo {public static void main(String[] args) {// 创建集合对象// 自然顺序进行排序TreeSet<Integer> ts = new TreeSet<Integer>();// 创建元素并添加// 20,18,23,22,17,24,19,18,24ts.add(20);ts.add(18);ts.add(23);ts.add(22);ts.add(17);ts.add(24);ts.add(19);ts.add(18);ts.add(24);// 遍历for (Integer i : ts) {System.out.println(i);}}
}

运行结果为:
但是对自定义对象呢?
[java] view plaincopyprint?
  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. ts.add(s1);
  13. ts.add(s2);
  14. ts.add(s3);
  15. ts.add(s4);
  16. ts.add(s5);
  17. ts.add(s6);
  18. //遍历
  19. for(Student s:ts){
  20. System.out.println(s.getName()+”———–”+s.getAge());
  21. }
  22. }
  23. }
public class TreeSetDemo02 {public static void main(String[] args) {TreeSet<Student> ts=new TreeSet<Student>();     //创建元素对象Student s1=new Student("zhangsan",20);Student s2=new Student("lis",22);Student s3=new Student("wangwu",24);Student s4=new Student("chenliu",26);Student s5=new Student("zhangsan",22);Student s6=new Student("qianqi",24);//将元素对象添加到集合对象中ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);ts.add(s6);//遍历for(Student s:ts){System.out.println(s.getName()+"-----------"+s.getAge());}}
}
Student类:
[java] view plaincopyprint?
  1. public class Student {
  2. private String name;
  3. private int age;
  4. public Student() {
  5. super();
  6. // TODO Auto-generated constructor stub
  7. }
  8. public Student(String name, int age) {
  9. super();
  10. this.name = name;
  11. this.age = age;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public int getAge() {
  20. return age;
  21. }
  22. public void setAge(int age) {
  23. this.age = age;
  24. }
  25. }
public class Student {private String name;private int age;public Student() {super();// TODO Auto-generated constructor stub}   public Student(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

运行结果:

原因分析:
由于不知道该安照那一中排序方式排序,所以会报错。
解决方法:
1.自然排序
2.比较器排序

2.自然排序

自然排序要进行一下操作:
1.Student类中实现  Comparable<T>接口
2.重写Comparable接口中的Compareto方法
 int compareTo(T o)
          比较此对象与指定对象的顺序。
故Student类为:特别注意在重写Compareto方法时,注意排序 
[java] view plaincopyprint?
  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. public Student() {
  11. super();
  12. // TODO Auto-generated constructor stub
  13. }
  14. public Student(String name, int age) {
  15. super();
  16. this.name = name;
  17. this.age = age;
  18. }
  19. public String getName() {
  20. return name;
  21. }
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25. public int getAge() {
  26. return age;
  27. }
  28. public void setAge(int age) {
  29. this.age = age;
  30. }
  31. @Override
  32. public int compareTo(Student s) {
  33. //return -1; //-1表示放在红黑树的左边,即逆序输出
  34. //return 1;  //1表示放在红黑树的右边,即顺序输出
  35. //return o;  //表示元素相同,仅存放第一个元素
  36. //主要条件 姓名的长度,如果姓名长度小的就放在左子树,否则放在右子树
  37. int num=this.name.length()-s.name.length();
  38. //姓名的长度相同,不代表内容相同,如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。
  39. //如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。
  40. //如果这两个字符串相等,则结果为 0
  41. int num1=num==0?this.name.compareTo(s.name):num;
  42. //姓名的长度和内容相同,不代表年龄相同,所以还要判断年龄
  43. int num2=num1==0?this.age-s.age:num1;
  44. return num2;
  45. }
  46. }
package xfcy_04;
/*** Student类* @author 晓风残月**/
public class Student implements Comparable<Student> {private String name;private int age;public Student() {super();// TODO Auto-generated constructor stub}   public Student(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic int compareTo(Student s) {//return -1; //-1表示放在红黑树的左边,即逆序输出//return 1;  //1表示放在红黑树的右边,即顺序输出//return o;  //表示元素相同,仅存放第一个元素//主要条件 姓名的长度,如果姓名长度小的就放在左子树,否则放在右子树int num=this.name.length()-s.name.length();  //姓名的长度相同,不代表内容相同,如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。//如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。//如果这两个字符串相等,则结果为 0int num1=num==0?this.name.compareTo(s.name):num;//姓名的长度和内容相同,不代表年龄相同,所以还要判断年龄int num2=num1==0?this.age-s.age:num1;return num2;}}

而主类中为:
[java] view plaincopyprint?
  1. package xfcy_04;
  2. import java.util.TreeSet;
  3. /*
  4. * TreeSet存储自定义对象并保证排序和唯一。
  5. *
  6. * 需求:请按照姓名的长度排序
  7. */
  8. public class TreeSetDemo02 {
  9. public static void main(String[] args) {
  10. //创建集合对象
  11. TreeSet<Student> ts=new TreeSet<Student>();
  12. //创建元素对象
  13. Student s1=new Student(“zhangsan”,20);
  14. Student s2=new Student(“lis”,22);
  15. Student s3=new Student(“wangwu”,24);
  16. Student s4=new Student(“chenliu”,26);
  17. Student s5=new Student(“zhangsan”,22);
  18. Student s6=new Student(“qianqi”,24);
  19. //将元素对象添加到集合对象中
  20. ts.add(s1);
  21. ts.add(s2);
  22. ts.add(s3);
  23. ts.add(s4);
  24. ts.add(s5);
  25. ts.add(s6);
  26. //遍历
  27. for(Student s:ts){
  28. System.out.println(s.getName()+”———–”+s.getAge());
  29. }
  30. }
  31. }
package xfcy_04;import java.util.TreeSet;/*
* TreeSet存储自定义对象并保证排序和唯一。* * 需求:请按照姓名的长度排序*/
public class TreeSetDemo02 {public static void main(String[] args) {//创建集合对象        TreeSet<Student> ts=new TreeSet<Student>();//创建元素对象Student s1=new Student("zhangsan",20);Student s2=new Student("lis",22);Student s3=new Student("wangwu",24);Student s4=new Student("chenliu",26);Student s5=new Student("zhangsan",22);Student s6=new Student("qianqi",24);//将元素对象添加到集合对象中ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);ts.add(s6);//遍历for(Student s:ts){System.out.println(s.getName()+"-----------"+s.getAge());}}
}

运行结果:

3、比较器排序

比较器排序步骤:
1.单独创建一个比较类,这里以MyComparator为例,并且要让其继承Comparator<T>接口
2.重写Comparator接口中的Compare方法
 int compare(T o1,T o2)
          比较用来排序的两个参数。
3.在主类中使用下面的 构造方法
TreeSet(Comparator<? superE> comparator)
          构造一个新的空 TreeSet,它根据指定比较器进行排序。
主类:
[java] view plaincopyprint?
  1. package xfcy_04;
  2. import java.util.TreeSet;
  3. /*
  4. * TreeSet存储自定义对象并保证排序和唯一。
  5. *
  6. * 需求:请按照姓名的长度排序
  7. */
  8. public class TreeSetDemo02 {
  9. public static void main(String[] args) {
  10. //创建集合对象
  11. //TreeSet(Comparator<? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。
  12. TreeSet<Student> ts=new TreeSet<Student>(new MyComparator());
  13. //创建元素对象
  14. Student s1=new Student(“zhangsan”,20);
  15. Student s2=new Student(“lis”,22);
  16. Student s3=new Student(“wangwu”,24);
  17. Student s4=new Student(“chenliu”,26);
  18. Student s5=new Student(“zhangsan”,22);
  19. Student s6=new Student(“qianqi”,24);
  20. //将元素对象添加到集合对象中
  21. ts.add(s1);
  22. ts.add(s2);
  23. ts.add(s3);
  24. ts.add(s4);
  25. ts.add(s5);
  26. ts.add(s6);
  27. //遍历
  28. for(Student s:ts){
  29. System.out.println(s.getName()+”———–”+s.getAge());
  30. }
  31. }
  32. }
package xfcy_04;import java.util.TreeSet;/*
* TreeSet存储自定义对象并保证排序和唯一。* * 需求:请按照姓名的长度排序*/
public class TreeSetDemo02 {public static void main(String[] args) {//创建集合对象//TreeSet(Comparator<? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。TreeSet<Student> ts=new TreeSet<Student>(new MyComparator());//创建元素对象Student s1=new Student("zhangsan",20);Student s2=new Student("lis",22);Student s3=new Student("wangwu",24);Student s4=new Student("chenliu",26);Student s5=new Student("zhangsan",22);Student s6=new Student("qianqi",24);//将元素对象添加到集合对象中ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);ts.add(s6);//遍历for(Student s:ts){System.out.println(s.getName()+"-----------"+s.getAge());}}
}

MyComparator类:
[java] view plaincopyprint?
  1. package xfcy_04;
  2. import java.util.Comparator;
  3. public class MyComparator implements Comparator<Student>{
  4. @Override
  5. public int compare(Student s1,Student s2) {
  6. // 姓名长度
  7. int num = s1.getName().length() - s2.getName().length();
  8. // 姓名内容
  9. int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
  10. // 年龄
  11. int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
  12. return num3;
  13. }
  14. }
package xfcy_04;import java.util.Comparator;public class MyComparator implements Comparator<Student>{@Overridepublic int compare(Student s1,Student s2) {// 姓名长度int num = s1.getName().length() - s2.getName().length();// 姓名内容int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;// 年龄int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;return num3;}}

学生类(不需要继承Comparetable接口)

[java] view plaincopyprint?
  1. package xfcy_04;
  2. /**
  3. * Student类
  4. * @author 晓风残月
  5. *
  6. */
  7. public class Student{
  8. private String name;
  9. private int age;
  10. public Student() {
  11. super();
  12. // TODO Auto-generated constructor stub
  13. }
  14. public Student(String name, int age) {
  15. super();
  16. this.name = name;
  17. this.age = age;
  18. }
  19. public String getName() {
  20. return name;
  21. }
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25. public int getAge() {
  26. return age;
  27. }
  28. public void setAge(int age) {
  29. this.age = age;
  30. }
  31. }
package xfcy_04;
/*** Student类* @author 晓风残月**/
public class Student{private String name;private int age;public Student() {super();// TODO Auto-generated constructor stub}   public Student(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}

运行结果:

4.比较器修改

由于单独创建一个类不是特别好,因而可以将MyComparetor的内容直接写到主类中
[java] view plaincopyprint?
  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. Student s1 = new Student(“linqingxia”, 27);
  20. Student s2 = new Student(“zhangguorong”, 29);
  21. Student s3 = new Student(“wanglihong”, 23);
  22. Student s4 = new Student(“linqingxia”, 27);
  23. Student s5 = new Student(“liushishi”, 22);
  24. Student s6 = new Student(“wuqilong”, 40);
  25. Student s7 = new Student(“fengqingy”, 22);
  26. Student s8 = new Student(“linqingxia”, 29);
  27. // 添加元素
  28. ts.add(s1);
  29. ts.add(s2);
  30. ts.add(s3);
  31. ts.add(s4);
  32. ts.add(s5);
  33. ts.add(s6);
  34. ts.add(s7);
  35. ts.add(s8);
  36. // 遍历
  37. for (Student s : ts) {
  38. System.out.println(s.getName() + ”—” + s.getAge());
  39. }
  40. }
  41. }
public class TreeSetDemo {public static void main(String[] args) {// 如果一个方法的参数是接口,那么真正要的是接口的实现类的对象// 而匿名内部类就可以实现这个东西TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {// 姓名长度int num = s1.getName().length() - s2.getName().length();// 姓名内容int num2 = num == 0 ? s1.getName().compareTo(s2.getName()): num;// 年龄int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;return num3;}});// 创建元素Student s1 = new Student("linqingxia", 27);Student s2 = new Student("zhangguorong", 29);Student s3 = new Student("wanglihong", 23);Student s4 = new Student("linqingxia", 27);Student s5 = new Student("liushishi", 22);Student s6 = new Student("wuqilong", 40);Student s7 = new Student("fengqingy", 22);Student s8 = new Student("linqingxia", 29);// 添加元素ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);ts.add(s6);ts.add(s7);ts.add(s8);// 遍历for (Student s : ts) {System.out.println(s.getName() + "---" + s.getAge());}}
}

运行结果也如同上面一样

5.总结

A:自然排序:要在自定义类中实现Comparerable<T>接口  ,并且重写compareTo方法
B:比较器排序:在自定义类中实现Comparetor<t>接口,重写

原文链接:http://blog.csdn.net/xiaofei__/article/details/53138681

TreeSet的两种排序方式相关推荐

  1. Java两种排序方式快慢比较

    2019独角兽企业重金招聘Python工程师标准>>> Java中List的排序方式有两种,现在我们测试下这两种排序方式的快慢吧,我们需要用到两个类, 一个是运行程序的Main类,另 ...

  2. java treeset比较,java中TreeSet的两种排序比较的方式

    第一种是使得元素具有比较性 第二种是让集合具有比较性 具体代码步骤如下: import java.util.*; /* * TreeSet:可以自动对对集合中的元素进行排序 * 第一种比较方式 * 步 ...

  3. mysql中两次排序_MySQL中的两种排序方式: index和filesort

    index :通过有序索引顺序扫描直接返回有序数据,不需要额外的排序,操作效率较高. filesort:通过对返回数据进行排序,filesort 并不代表通过磁盘文件排序,而是说明进行了一个排序操作, ...

  4. 二分查找算法的两种实现方式:非递归实现和递归实现

    二分查找的条件是对一组有序数组的查找,这一点很容易忘记,在使用二分查找的时候先要对数组进行排序. 先说一下二分查找的思路:一个有序数组,想要查找一个数字key的下标,首先算出中间下标mid,利用mid ...

  5. 快排的c++实现(两种实现方式)

    快速排序算法是现在用的最广的排序算法,也是效率最高的.它有两种实现方式,一种是定轴法,另外一种是挖坑法.这里简单介绍一下两种实现方法的思想,并附上C++实现代码. (一)定轴法: 1.备份对轴(首记录 ...

  6. go kegg_玩转GO和KEGG富集因子图的N种姿势: 3种数据处理(含在线筛选条目),3种排序方式,本地交互图片...

    适用场景 富集性分析是各组学进行数据分析的必备分析项,其中,尤以GO和KEGG富集因子图最为常见,见封面图.这张图非常经典,相比于其他富集分析结果,它包含了基因数目.p值和富集因子三个维度的信息量,更 ...

  7. 两种排序方法(直接判断)

    题目描述 考拉有n个字符串字符串,任意两个字符串长度都是不同的.考拉最近学习到有两种字符串的排序方法: 1.根据字符串的字典序排序.例如: "car" < "car ...

  8. halcon颜色识别的两种简单方式

    颜色识别的两种简单方式: 1.单通道方式: 原理:通过不同颜色在灰度图中的阈值范围不同来区分颜色(理论上这种方式不推荐,但在一定情况下适用) 材料: halcon代码: dev_close_windo ...

  9. day06-元组字典集合常用两种排序

    Day06-元组&字典&集合&常用两种排序 一.tuple元组 1.概述 和列表相似,本质上是一种有序的集合 元组和列表的不同之处: ​ a.列表:[ ] 元组:( ) ​ b ...

  10. C++中的两种绑定方式(静态绑定、动态绑定)

    两种绑定方式 静态绑定:在编译时刻,根据指针或引用变量的静态类型来决定成员函数属于哪一个类. 动态绑定:在运行时刻,根据指针或引用变量实际指向或引用的对象类型(动态类型)来确定成员函数属于哪一个类. ...

最新文章

  1. leetcode(1)485——最大连续 1 的个数(C++)
  2. 47_pytorch循环神经网络(学习笔记)
  3. mha如何管理多套mysql集群_Mysql 集群高可用方案 MHA
  4. C# 值类型的局限性
  5. 低功耗/远距离lora模块:物联网智能家居、抄表多领域应用SX1262芯片方案
  6. 使用windows Phone 集成横幅广告教程
  7. docker安装es+kibana
  8. HTTPS数字证书原理
  9. Job for tomcat.service failed because the control process exited with error code 解决办法:
  10. 广东省中医院微信公众号医保个账支付功能
  11. cloudera-scm-agent start 启动失败
  12. 微信小程序新手留言板
  13. android官网m魅族15,还是熟悉的味道,魅族三款15系新机现身安卓官网
  14. XBox360-双光盘游戏自制GOD
  15. 从“历年全国出生人口”看,如何用Python来制作可视化动态图
  16. 单片机外设系列之一时钟芯片DS1302
  17. ubuntu WPS升级后打不开
  18. 自动为计算机配置ip的协议,电脑自动获取IP地址----DHCP动态主机配置协议
  19. 我的win7 64 激活过了,但是计算机-属性仍然显示“未激活此WIndows副本,单击此处立即激活...
  20. 代理商管理系统/代理商信息管理系统

热门文章

  1. Gucci“瑕疵”口红海报是一种对审“丑”广告的致敬吗?
  2. mysql 判断当前星期_MySQL获取星期的函数
  3. Day434.订单库存服务分布式事务的最终解决 -谷粒商城
  4. 2017年中国网络安全报告
  5. 啸叫抑制(howling suppression)
  6. Top100图神经网络论文大盘点
  7. 使用 Ubuntu 搭建 Minecraft 官方或Mod(Forge)服务器
  8. 人月神话(二)——为什么巴比伦塔会失败
  9. Unity3D之FingerGestures使用
  10. Raspberry Pi 上手准备