java集合TreeSet類
/**
* Set接口的實(shí)現(xiàn)類TreeSet
* TreeSet通過(guò)TreeMap的key存儲(chǔ)元素 并且對(duì)存儲(chǔ)的元素進(jìn)行排序
*/
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);
? ? ? ?//結(jié)果為[B, a, c] TreeSet會(huì)調(diào)用String類實(shí)現(xiàn)的Comparable<T>接口的compareTo(T)方法對(duì)字符串進(jìn)行排序
? ? ? ?// String實(shí)現(xiàn)的compareTo排序規(guī)則為從第一位字符開(kāi)始按照Unicode字符集/字典逐字比較返回第一個(gè)不同的字符的差,直到一個(gè)字符串全部取完則返回長(zhǎng)度差
? ? ? ?//TreeSet的排序可以根據(jù)元素自身實(shí)現(xiàn)的compareTo規(guī)則 或者通過(guò)比較器comparator指定比較規(guī)則
? ?}
}
class Users1{
? ?//自定義對(duì)象通過(guò)TreeSet存儲(chǔ)
? ?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);
? ? ? ?/* 執(zhí)行時(shí)報(bào)錯(cuò)
? ? ? ?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類型強(qiáng)轉(zhuǎn)異常 User1類型不能強(qiáng)轉(zhuǎn)為Comparable類型
? ? ? ? ? ?TreeSet存儲(chǔ)元素時(shí)會(huì)對(duì)元素進(jìn)行排序 因此TreeSet要求存儲(chǔ)的類型提供排序的規(guī)則
? ? ? ? ? ?元素沒(méi)有指定規(guī)則時(shí)默認(rèn)根據(jù)Comparable接口的compareTo方法的規(guī)則進(jìn)行排序 即用引用類型Comparable變量指向Users1類形成多態(tài) 通過(guò)引用變量.compareTo進(jìn)行比較
? ? ? ? ? ?引用變量引用時(shí)發(fā)生強(qiáng)轉(zhuǎn) Users1不能強(qiáng)轉(zhuǎn)為Comparable所以拋異常
? ? ? ? */
? ?}
}
class Users2 implements Comparable<Users2>{
? ?//使自定義類實(shí)現(xiàn)Comparable接口 即可使用TreeSet存儲(chǔ) Comparable<T>泛型接口 將泛型設(shè)為自定義的類免去運(yùn)行時(shí)強(qiáng)轉(zhuǎn)
? ?//接口要求實(shí)現(xiàn)接口的抽象方法compareTo(T)
? ?String name;
? ?int id;
? ?public Users2(String name, int id) {
? ? ? ?this.name = name;
? ? ? ?this.id = id;
? ?}
? ?@Override
? ?public int compareTo(Users2 u) {
? ? ? ?//重寫(xiě)compareTo() 返回類型int 當(dāng)返回正數(shù)時(shí)表示需要交換this和u的位置 當(dāng)返回負(fù)數(shù)時(shí)表示不交換 當(dāng)返回0時(shí)表示兩對(duì)象位置相同
? ? ? ?if (this.id>u.id)return 1;
? ? ? ?//設(shè)定當(dāng)this的id大于u的id時(shí)交換兩個(gè)對(duì)象的位置
? ? ? ?if (this.id==u.id)return this.name.compareTo(u.name);
? ? ? ?//當(dāng)id相同時(shí)比較name屬性 name類型為String String類本身已經(jīng)實(shí)現(xiàn)了Comparable接口 所以可以直接調(diào)用String的compareTo方法對(duì)name屬性做判斷 調(diào)用方法后不需要加工直接返回
? ? ? ?//注意比較的是name屬性 所以實(shí)參u也要.name
? ? ? ?return -1;
? ? ? ?//當(dāng)this.id<u.id時(shí)返回-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);
? ? ? ?//結(jié)果為[{name='Jane', id=1}, {name='Tom', id=2}, {name='Tony', id=2}]
? ? ? ?//id都為2時(shí)比較字符串 前兩位相同 第三位n>m返回1交換
? ?}
}
class Users3{
? ?//通過(guò)比較器規(guī)定規(guī)則 元素本身不需要實(shí)現(xiàn)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) {
? ? ? ?//要求重寫(xiě)compare方法 比較器本身不是要比較的類 所以需要將比較雙方都作為參數(shù)傳進(jìn)來(lái)
? ? ? ?if (o1.getPassword()>o2.getPassword())return 1;
? ? ? ?//方法的定義和compareTo基本一致
? ? ? ?if (o1.getPassword()==o2.getPassword())return o1.getName().compareTo(o2.getName());
? ? ? ?//通過(guò)get方法從Users3類外部調(diào)用
? ? ? ?return -1;
? ?}
? ?public static void main(String[] args) {
? ? ? ?Set<Users3> ts = new TreeSet<>(new UserComparator());
? ? ? ?//new一個(gè)比較器對(duì)象傳參給TreeSet構(gòu)造器
? ? ? ?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通過(guò)比較器的規(guī)則對(duì)存入的元素進(jìn)行排序 結(jié)果為[{name='Jack', password='111111'}, {name='Jane', password='111111'}, {name='Joe', password='123456'}]
? ? ? ?Set<Users3> ts2 = new TreeSet<>(new Comparator<Users3>() {
? ? ? ? ? ?//匿名內(nèi)部類
? ? ? ? ? ?@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);
? ?}
}