赞
踩
TreeSet集合底层采用红黑树算法,会对存储的元素默认使用自然排序(从小到大).
注意: 必须保证TreeSet集合中的元素对象是相同的数据类型,否则报错.
各种数据类型自然排序规则
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方法
举例:
- import java.util.Set;
- import java.util.TreeSet;
-
- public class SetDemo4 {
- public static void main(String[] args) {
- Set<String> set = new TreeSet<>();
-
- set.add("a");
- set.add("A");
- set.add("abc");
- set.add("B");
-
- System.out.println(set);//打印结果,已经排好序了[A, B, a, abc],按照字符串的Unicode值排序
- }
- }
在这里我们如果要想自己定义的类在TreeSet中也能实现自然排序,那么就要根据上面的步骤来实现:
举个例子:首先定义一个Student类,这个类要实现Comparable接口,然后覆盖CompareTo方法,自定义自己需要排序的规则,比如我们这里按照学生的姓名的长度进行自然排序:
- class Student implements Comparable<Student>{
- private int id;
- private String name;
-
- public Student(int id, String name) {
- super();
- this.id = id;
- this.name = name;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- @Override
- public String toString() {
- return "Student [id=" + id + ", name=" + name + "]";
- }
-
- /**
- * 覆盖compareTo方法
- * 根据学生的姓名长度排序
- */
- public int compareTo(Student stu) {
- if (this.getName().length()>stu.getName().length()) {
- return 1;
- }else if (this.getName().length()<stu.getName().length()) {
- return -1;
- }else {
- return 0; //长度相同
- }
- }
-
- }
测试:打印结果,姓名长度由短到长来排序的
- import java.util.Set;
- import java.util.TreeSet;
-
- public class SetDemo4 {
- public static void main(String[] args) {
- Set<Student> set = new TreeSet<>();
-
- set.add(new Student(1, "聂小倩"));
- set.add(new Student(1, "西门吹雪"));
- set.add(new Student(1, "哥"));
- set.add(new Student(1, "孙斌"));
-
- System.out.println(set);
- //打印结果看下面,说明是按照名字长度从小到大的自然顺序来排序的
- //[Student [id=1, name=哥], Student [id=1, name=孙斌], Student [id=1, name=聂小倩], Student [id=1, name=西门吹雪]]
- }
- }
在TreeSet构造函数中,有一个构造函数可以传入一个比较器对象,他是一个接口,我们需要提供实现类,并覆盖compare方法再编写比较规则.
同样的,我们举个例子,也是按照学生姓名长度排序:
首先也是定义一个学生类:
- class Student{
- private int id;
- private String name;
-
- public Student(int id, String name) {
- super();
- this.id = id;
- this.name = name;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- @Override
- public String toString() {
- return "Student [id=" + id + ", name=" + name + "]";
- }
- }
然后定义比较器类:
- import java.util.Comparator;
-
- //比较器类
- class NameLengthComparator implements Comparator<Student> {
- /**
- * 覆盖compare方法
- * 比较规则:同样是根据学生的姓名长度排序
- */
- public int compare(Student s1, Student s2) {
- if (s1.getName().length() > s2.getName().length()) {
- return 1;
- } else if (s1.getName().length() < s2.getName().length()) {
- return -1;
- } else {
- return 0;
- }
- }
-
- }
测试:
- import java.util.Set;
- import java.util.TreeSet;
-
- public class SetDemo5 {
- public static void main(String[] args) {
- //创建set对象的时候要传入比较器类对象
- Set<Student> set = new TreeSet<>(new NameLengthComparator());
-
- set.add(new Student(1, "聂小倩"));
- set.add(new Student(1, "西门吹雪"));
- set.add(new Student(1, "哥"));
- set.add(new Student(1, "孙斌"));
-
- System.out.println(set);
- }
- }
打印结果:
[Student2 [id=1, name=哥], Student2 [id=1, name=孙斌], Student2 [id=1, name=聂小倩], Student2 [id=1, name=西门吹雪]]
既然是定制排序,你可以修改排序规则,按照从长到短来排序,只需要修改比较器类的实现规则
- import java.util.Comparator;
-
- //比较器类
- class NameLengthComparator implements Comparator<Student> {
- /**
- * 覆盖compare方法
- * 比较规则:同样是根据学生的姓名长度排序
- */
- public int compare(Student s1, Student s2) {
- if (s1.getName().length() < s2.getName().length()) {
- return 1;
- } else if (s1.getName().length() > s2.getName().length()) {
- return -1;
- } else {
- return 0;
- }
- }
-
- }
将if中的>和<修改一下就行了
对于TreeSet集合来说,要么使用自然排序,要么使用定制排序.
判断两个对象是否相等的规则:
自然排序: compareTo方法返回0;
定制排序: compare方法返回0;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。