TreeSet集合的特点
- 不包含重复元素 (存储的元素要重写equals()和hashCode()方法)
- 没有索引
- 可以将元素按照规则进行排序(要自定义排序规则)
- 底层: 红黑树
TreeSet集合的两种排序方式
- 自然排序
- 使用空参构造创建TreeSet集合
- 自定义的类实现Comparable接口
- 重写Comparable接口的compareTo()方法
class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
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;
}
@Override
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
// 先根据年龄升序排列,年龄相同则按照姓名的字典序排列
@Override
public int compareTo(Student o) {
int res = this.age - o.getAge();
return res == 0 ? this.name.compareTo(o.getName()) : res;
}
}
public class Test1 {
public static void main(String[] args) {
// 利用空参构造函数创建TreeSet集合
TreeSet<Student> ts = new TreeSet<>();
// 添加元素
ts.add(new Student("xiaobo", 21));
// Student类重写了equals()和hashCode()方法,保证元素唯一
ts.add(new Student("xiaobo", 21));
ts.add(new Student("xinru", 21));
ts.add(new Student("haha", 19));
ts.add(new Student("xiaobai", 22));
// 遍历集合
for (Student stu : ts) {
System.out.println(stu);
}
/* 答案:
Student{name = haha, age = 19}
Student{name = xiaobo, age = 21}
Student{name = xinru, age = 21}
Student{name = xiaobai, age = 22}*/
}
}
- 比较器排序
- TreeSet的带参构造方法使用的是比较器排序对元素进行排序的
- 比较器排序就是让TreeSet集合构造方法接收Comparator接口的实现类对象
- 重写Comparator接口中compare(T o1, T o2)方法, 指定排序规则
- 注意: o1代表的是当前往集合中添加的元素, o2代表的是集合中已经存在的元素, 排序原理和自然排序相同
public class Test1 {
public static void main(String[] args) {
// 利用有参构造函数创建TreeSet集合 利用匿名内部类实现Comparator接口的子类对象
TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int res = o1.getAge() - o2.getAge();
return res == 0 ? o1.getName().compareTo(o2.getName()) : res;
}
});
// 添加元素
ts.add(new Student("xiaobo", 21));
// Student类重写了equals()和hashCode()方法,保证元素唯一
ts.add(new Student("xiaobo", 21));
ts.add(new Student("xinru", 21));
ts.add(new Student("haha", 19));
ts.add(new Student("xiaobai", 22));
// 遍历集合
for (Student stu : ts) {
System.out.println(stu);
}
/* 答案:
Student{name = haha, age = 19}
Student{name = xiaobo, age = 21}
Student{name = xinru, age = 21}
Student{name = xiaobai, age = 22}*/
}
}
-
两种排序方式的比较
- 如果Java提供好的类已经定义了自然排序排序规则,那么我们可以使用比较器排序进行替换( 如果自然排序和比较器排序都存在, 那么会使用比较器排序 )
-
两种方式中,关于返回值的规则
- 如果返回值为负数,表示当前存入的元素是较小值,存左边
- 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存
- 如果返回值为正数,表示当前存入的元素是较大值,存右边