TreeSet
实现是基于TreeMap 实现的;
TreeSet中的元素是有序的。此时的有序是指的元素的顺序是字典顺序。
排序方式:
自然排序
定制排序
public static void main(String[] args) {
//创建集合
TreeSet ts = new TreeSet();
// 添加元素
ts.add(10);
ts.add(40);
ts.add(30);
ts.add(50);
ts.add(20);
ts.add(10);
for (Object obj : ts){
System.out.println(obj);
}
}
Integer类实现对象的排序
TreeSet存储自定义对象
自然排序
自定义对象需要实现Comparable接口 此处体现的是接口的多态。
凡事存入到TreeSet集合中的对象,都需要实现排序接口。
package cn.lanqiao.demo;
import java.util.Objects;
public class Student implements Comparable{
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 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(Object o) {
// 根据年龄排序
// 获取当前对象的年龄
int age1 = this.getAge();
// 获取比较对象的年龄
Student st = (Student)o;
int age2 = st.getAge();
return age1 - age2;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
System.out.println("---------------------");
TreeSet ts1 = new TreeSet();
Student st1 = new Student("张三",20);
Student st2 = new Student("李四",22);
Student st3 = new Student("王五",18);
Student st4 = new Student("赵六",21);
ts1.add(st1);
ts1.add(st2);
ts1.add(st3);
ts1.add(st4);
for (Object obj : ts1){
System.out.println(obj);
}
按照姓名排序:
如果字符串是英文 则是按照字典顺序进行排序
如果是中文,则是按照中文的UniCode码进行排序
在排序中,如果是中文,如果第一个字相同,则按照第二个字进行排序
如果是英文,如果第一个字母相同,则按照第二个字母排序
思考练习:
优先按照年龄排序,如果年龄相同,则按照姓名排序。
@Override
public int compareTo(Object o) {
//优先按照年龄排序,如果年龄相同,则按照姓名排序
Student st =(Student) o;
int res = this.getAge().compareTo(st.getAge());
// if(res == 0){
// res = this.getName().compareTo(st.getName());
// }
int result = res ==0 ? this.getName().compareTo(st.getName()):res;
return result;
}
按照年龄进行降序排序
@Override
public int compareTo(Object o) {
//优先按照年龄排序,如果年龄相同,则按照姓名排序
Student st =(Student) o;
int res = this.getAge().compareTo(st.getAge());
// if(res == 0){
// res = this.getName().compareTo(st.getName());
// }
int result = res ==0 ? this.getName().compareTo(st.getName()):res;
return -result;//将比较的结果取反
}
结论:
用TreeSet存储自定义 对象,使用无参构造来创建集合,此时默认使用的是自然排序,对元素的排序 需要让元素的所属类实现Comparable接口,并重写compareTo方法
重写的时候,可以自定义排序规则。必须区分清楚主要条件和次要条件,同时要注意排序的要求(升序、降序)
定制排序:
在创建集合的时候 需要指定一个Compareator接口的对象
方式一:编写一个普通类,去实现接口
public class ComparatorStu implements Comparator {
@Override
public int compare(Object o1, Object o2) {
// 将对象转换为Student
Student st1 = (Student)o1;
Student st2 = (Student)o2;
return st1.getAge().compareTo(st2.getAge());
}
}
方式二:使用内部类来实现
package cn.lanqiao.demo;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
Comparator com = new ComparatorStudent();
//创建集合
TreeSet ts1 = new TreeSet(com);
Student st1 = new Student("张三",20);
Student st2 = new Student("李四",22);
Student st3 = new Student("王五",18);
Student st4 = new Student("张六",23);
ts1.add(st1);
ts1.add(st2);
ts1.add(st3);
ts1.add(st4);
for (Object obj : ts1){
System.out.println(obj);
}
}
private static class ComparatorStudent implements Comparator{
@Override
public int compare(Object o1, Object o2) {
// 将对象转换为Student
Student st1 = (Student)o1;
Student st2 = (Student)o2;
return st1.getAge().compareTo(st2.getAge());
}
}
}
方式三:使用匿名内部类
public class TreeSetDemo {
public static void main(String[] args) {
//创建集合
TreeSet ts1 = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
// 将对象转换为Student
Student st1 = (Student)o1;
Student st2 = (Student)o2;
return st1.getAge().compareTo(st2.getAge());
}
});
Student st1 = new Student("张三",20);
Student st2 = new Student("李四",22);
Student st3 = new Student("王五",18);
Student st4 = new Student("张六",23);
ts1.add(st1);
ts1.add(st2);
ts1.add(st3);
ts1.add(st4);
for (Object obj : ts1){
System.out.println(obj);
}
}
}
实现方式的比较★
面试题
package cn.lanqiao.demo;
import java.util.Comparator;
import java.util.HashSet;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
HashSet set = new HashSet();
Person p1 = new Person(1001,"AA");
Person p2 = new Person(1002,"BB");
set.add(p1);//p1 在集合中的存储位置是由1001 和AA计算所得
set.add(p2);
System.out.println(set);
p1.setName("CC");//将AA 改为了CC
System.out.println(set);
boolean b = set.remove(p1);//此时会根据p1的hash值来计算需要移除的元素所在的位置
System.out.println(b);//false'
System.out.println(set);//
set.add(new Person(1001,"CC"));//存储的位置是由1001和CC计算所得
System.out.println(set);//
set.add(new Person(1001,"AA"));//虽然计算得到的位置和第二个对象相同,但是hash值不同且equals返回false
System.out.println(set);//
}
}