/**
* Set接口的实现类TreeSet
* TreeSet通过TreeMap的key存储元素 并且对存储的元素进行排序
*/
public class TestTreeSet {
public static void main(String[] args) {
Set<String> ts1 = new TreeSet<>();
//TreeSet基本方法的使用和HashSet相同
ts1.add(“a”);
ts1.add(“B”);
ts1.add(“c”);
System.out.println(ts1);
//结果为[B, a, c] TreeSet会调用 String 类实现的Comparable<T>接口的compareTo(T)方法对 字符串 进行排序
// String实现的 compareTo 排序规则为从第一位字符开始按照 Unicode 字符集/字典逐字比较返回第一个不同的字符的差,直到一个字符串全部取完则返回长度差
//TreeSet的排序可以根据元素自身实现的compareTo规则 或者通过比较器comparator指定比较规则
}
}
class Users1{
//自定义对象通过TreeSet存储
String name;
int age;
public Users1(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Set<Users1> ts = new TreeSet<>();
Users1 u1 = new Users1(“Tony”,18);
Users1 u2 = new Users1(“Tom”,20);
ts.add(u1);
ts.add(u2);
System.out.println(ts);
/* 执行时报错
Exception in thread “main” java.lang.ClassCastException: Users1 cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1294)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
at Users1.main(TestTreeSet.java:34)
ClassCastException类型强转异常 User1类型不能强转为Comparable类型
TreeSet存储元素时会对元素进行排序 因此TreeSet要求存储的类型提供排序的规则
元素没有指定规则时默认根据Comparable接口的compareTo方法的规则进行排序 即用引用类型Comparable变量指向Users1类形成多态 通过引用变量.compareTo进行比较
引用变量引用时发生强转 Users1不能强转为Comparable所以抛异常
*/
}
}
class Users2 implements Comparable<Users2>{
//使自定义类实现Comparable接口 即可使用TreeSet存储 Comparable<T>泛型接口 将泛型设为自定义的类免去运行时强转
//接口要求实现接口的抽象方法compareTo(T)
String name;
int id;
public Users2(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public int compareTo(Users2 u) {
//重写compareTo() 返回类型int 当返回正数时表示需要交换this和u的位置 当返回负数时表示不交换 当返回0时表示两对象位置相同
if (this.id>u.id)return 1;
//设定当this的id大于u的id时交换两个对象的位置
if (this.id==u.id)return this.name.compareTo(u.name);
//当id相同时比较name属性 name类型为String String类本身已经实现了Comparable接口 所以可以直接调用String的compareTo方法对name属性做判断 调用方法后不需要加工直接返回
//注意比较的是name属性 所以实参u也要.name
return -1;
//当this.id<u.id时返回-1
}
@Override
public String toString() {
return “{” +
“name='” + name + ‘\” +
“, id=” + id +
‘}’;
}
public static void main(String[] args) {
Set<Users2> ts = new TreeSet<>();
Users2 u1 = new Users2(“Jane”,1);
Users2 u2 = new Users2(“Tony”,2);
Users2 u3 = new Users2(“Tom”,2);
ts.add(u1);
ts.add(u2);
ts.add(u3);
System.out.println(ts);
//结果为[{name=’Jane’, id=1}, {name=’Tom’, id=2}, {name=’Tony’, id=2}]
//id都为2时比较字符串 前两位相同 第三位n>m返回1交换
}
}
class Users3{
//通过比较器规定规则 元素本身不需要实现Comparable接口
private String name;
private int password;
public Users3(String name, int password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public int getPassword() {
return password;
}
@Override
public String toString() {
return “{” +
“name='” + name + ‘\” +
“, password='” + password + ‘\” +
‘}’;
}
}
class UserComparator implements Comparator<Users3>{
//comparator比较器 泛型接口 将T指定为Users3类
@Override
public int compare(Users3 o1, Users3 o2) {
//要求重写compare方法 比较器本身不是要比较的类 所以需要将比较双方都作为参数传进来
if (o1.getPassword()>o2.getPassword())return 1;
//方法的定义和compareTo基本一致
if (o1.getPassword()==o2.getPassword())return o1.getName().compareTo(o2.getName());
//通过get方法从Users3类外部调用
return -1;
}
public static void main(String[] args) {
Set<Users3> ts = new TreeSet<>(new UserComparator());
//new一个比较器对象传参给TreeSet构造器
Users3 u1 = new Users3(“Jane”,111111);
Users3 u2 = new Users3(“Jack”,111111);
Users3 u3 = new Users3(“Joe”,123456);
ts.add(u1);
ts.add(u2);
ts.add(u3);
System.out.println(ts);
//TreeSet通过比较器的规则对存入的元素进行排序 结果为[{name=’Jack’, password=’111111′}, {name=’Jane’, password=’111111′}, {name=’Joe’, password=’123456′}]
Set<Users3> ts2 = new TreeSet<>(new Comparator<Users3>() {
//匿名内部类
@Override
public int compare(Users3 o1, Users3 o2) {
if (o1.getPassword()>o2.getPassword())return 1;
return -1;
}
});
ts2.add(u1);
ts2.add(u2);
ts2.add(u3);
System.out.println(ts2);
}
}