当前位置:   article > 正文

java集合框架之TreeSet类_new treeset<>

new treeset<>

1.TreeSet介绍

TreeSet集合底层采用红黑树算法,会对存储的元素默认使用自然排序(从小到大).
注意: 必须保证TreeSet集合中的元素对象是相同的数据类型,否则报错.


2.TreeSet的排序规则

自然排序(从小到大):
TreeSet调用集合元素的compareTo方法来比较元素的大小关系,然后将集合元素按照升序排列(从小到大).
注意:要求TreeSet集合中元素得实现java.util.Comparable接口.

各种数据类型自然排序规则


java.util.Comparable接口:可比较的.
覆盖 public int compareTo(Object o)方法,在该方法中编写比较规则.
在该方法中,比较当前对象(this)和参数对象o做比较(严格上说比较的是对象中的数据,比如按照对象的年龄排序).
       this  >  o: 返回正整数.  1
       this <   o: 返回负整数.  -1
       this == o: 返回0.     此时认为两个对象为同一个对象.
--------------------------------------
在TreeSet的自然排序中,认为如果两个对象做比较的compareTo方法返回的是0,则认为是同一个对象.


从上图可知,基本上很多类都实现了这个接口,我们来看一下String类源码,可以看出String已经实现Comparable,并覆盖compareTo方法



举例:

  1. import java.util.Set;
  2. import java.util.TreeSet;
  3. public class SetDemo4 {
  4. public static void main(String[] args) {
  5. Set<String> set = new TreeSet<>();
  6. set.add("a");
  7. set.add("A");
  8. set.add("abc");
  9. set.add("B");
  10. System.out.println(set);//打印结果,已经排好序了[A, B, a, abc],按照字符串的Unicode值排序
  11. }
  12. }
在这里我们如果要想自己定义的类在TreeSet中也能实现自然排序,那么就要根据上面的步骤来实现:

举个例子:首先定义一个Student类,这个类要实现Comparable接口,然后覆盖CompareTo方法,自定义自己需要排序的规则,比如我们这里按照学生的姓名的长度进行自然排序:

  1. class Student implements Comparable<Student>{
  2. private int id;
  3. private String name;
  4. public Student(int id, String name) {
  5. super();
  6. this.id = id;
  7. this.name = name;
  8. }
  9. public int getId() {
  10. return id;
  11. }
  12. public void setId(int id) {
  13. this.id = id;
  14. }
  15. public String getName() {
  16. return name;
  17. }
  18. public void setName(String name) {
  19. this.name = name;
  20. }
  21. @Override
  22. public String toString() {
  23. return "Student [id=" + id + ", name=" + name + "]";
  24. }
  25. /**
  26. * 覆盖compareTo方法
  27. * 根据学生的姓名长度排序
  28. */
  29. public int compareTo(Student stu) {
  30. if (this.getName().length()>stu.getName().length()) {
  31. return 1;
  32. }else if (this.getName().length()<stu.getName().length()) {
  33. return -1;
  34. }else {
  35. return 0; //长度相同
  36. }
  37. }
  38. }
测试:打印结果,姓名长度由短到长来排序的

  1. import java.util.Set;
  2. import java.util.TreeSet;
  3. public class SetDemo4 {
  4. public static void main(String[] args) {
  5. Set<Student> set = new TreeSet<>();
  6. set.add(new Student(1, "聂小倩"));
  7. set.add(new Student(1, "西门吹雪"));
  8. set.add(new Student(1, "哥"));
  9. set.add(new Student(1, "孙斌"));
  10. System.out.println(set);
  11. //打印结果看下面,说明是按照名字长度从小到大的自然顺序来排序的
  12. //[Student [id=1, name=哥], Student [id=1, name=孙斌], Student [id=1, name=聂小倩], Student [id=1, name=西门吹雪]]
  13. }
  14. }


定制排序(比如从大到小,按照名字的长短来排序):
TreeSet构造器中传递java.lang.Comparator对象.覆盖public int compare(Object o1, Object o2)再编写比较规则.

在TreeSet构造函数中,有一个构造函数可以传入一个比较器对象,他是一个接口,我们需要提供实现类,并覆盖compare方法再编写比较规则.


同样的,我们举个例子,也是按照学生姓名长度排序:

首先也是定义一个学生类:

  1. class Student{
  2. private int id;
  3. private String name;
  4. public Student(int id, String name) {
  5. super();
  6. this.id = id;
  7. this.name = name;
  8. }
  9. public int getId() {
  10. return id;
  11. }
  12. public void setId(int id) {
  13. this.id = id;
  14. }
  15. public String getName() {
  16. return name;
  17. }
  18. public void setName(String name) {
  19. this.name = name;
  20. }
  21. @Override
  22. public String toString() {
  23. return "Student [id=" + id + ", name=" + name + "]";
  24. }
  25. }
然后定义比较器类:

  1. import java.util.Comparator;
  2. //比较器类
  3. class NameLengthComparator implements Comparator<Student> {
  4. /**
  5. * 覆盖compare方法
  6. * 比较规则:同样是根据学生的姓名长度排序
  7. */
  8. public int compare(Student s1, Student s2) {
  9. if (s1.getName().length() > s2.getName().length()) {
  10. return 1;
  11. } else if (s1.getName().length() < s2.getName().length()) {
  12. return -1;
  13. } else {
  14. return 0;
  15. }
  16. }
  17. }
测试:

  1. import java.util.Set;
  2. import java.util.TreeSet;
  3. public class SetDemo5 {
  4. public static void main(String[] args) {
  5. //创建set对象的时候要传入比较器类对象
  6. Set<Student> set = new TreeSet<>(new NameLengthComparator());
  7. set.add(new Student(1, "聂小倩"));
  8. set.add(new Student(1, "西门吹雪"));
  9. set.add(new Student(1, "哥"));
  10. set.add(new Student(1, "孙斌"));
  11. System.out.println(set);
  12. }
  13. }
打印结果:

[Student2 [id=1, name=哥], Student2 [id=1, name=孙斌], Student2 [id=1, name=聂小倩], Student2 [id=1, name=西门吹雪]]

既然是定制排序,你可以修改排序规则,按照从长到短来排序,只需要修改比较器类的实现规则

  1. import java.util.Comparator;
  2. //比较器类
  3. class NameLengthComparator implements Comparator<Student> {
  4. /**
  5. * 覆盖compare方法
  6. * 比较规则:同样是根据学生的姓名长度排序
  7. */
  8. public int compare(Student s1, Student s2) {
  9. if (s1.getName().length() < s2.getName().length()) {
  10. return 1;
  11. } else if (s1.getName().length() > s2.getName().length()) {
  12. return -1;
  13. } else {
  14. return 0;
  15. }
  16. }
  17. }
将if中的>和<修改一下就行了

对于TreeSet集合来说,要么使用自然排序,要么使用定制排序.
判断两个对象是否相等的规则:
自然排序:   compareTo方法返回0;
定制排序:  compare方法返回0;


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/1003445
推荐阅读
相关标签
  

闽ICP备14008679号