欢迎光临散文网 会员登陆 & 注册

java集合TreeSet类

2022-07-24 13:06 作者:虚云幻仙  | 我要投稿

/**
* 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);
   }
}

java集合TreeSet类的评论 (共 条)

分享到微博请遵守国家法律