美文网首页
集合框架Set----TreeSet

集合框架Set----TreeSet

作者: 东风谷123Liter | 来源:发表于2018-09-15 22:05 被阅读0次

    TreeSet是有序的。

    • 保存的元素会自动排序;
    • 排序方法是依据ASII码值进行排序的。
      简单实现:
      运行结果:
      下面我们来看TreeSet集合存储自定义对象:

    需求:

    用TreeeSet集合存储自定义对象Student;
    使其按学号进行排序,如果学号相同就按照名字的ASII值排序。

    思路:

    由于前路未卜,我们走一步看一步:

    import java.util.*;
    //定义Student类型
    class Student {
         private String name;
         private int number;
         Student(String n, int nu){
               this.name = name;
               this.number = number;
         }
         public String getName() {
               return name;
         }
         public int getNumber() {
               return number;
         }
    }
    class treeSetStudent {
         public static void main(String[] args) {
               //定义TreeSet集合来存储Student类型对象。
               TreeSet ts = new TreeSet();    
               ts.add(new Student("tom01",12));
               ts.add(new Student("tom07",22));
               ts.add(new Student("tom09",12));
               Iterator it = ts.iterator();
               while(it.hasNext()) {
                    Student st = (Student)it.next();
                    System.out.println(st.getName()+"....."+st.getNumber());
               }
         }
    }
    

    看似很完美,但结果却出乎意料:

    Exception in thread "main" java.lang.ClassCastException: jihe.Student cannot be cast to java.base/[java.lang.Comparable](http://java.lang.comparable/)
         at java.base/[java.util.TreeMap.compare](http://java.util.treemap.compare/)(TreeMap.java:1291)
         at java.base/java.util.TreeMap.put(TreeMap.java:536)
         at java.base/java.util.TreeSet.add(TreeSet.java:255)
         at jihe.treeSetStudent.main(treeSetStudent.java:25)
    

    从上面报错信息,我们可以发现类型映射异常:
    他说Student类型没办法映射到java.lang.Comparable类型!
    所以我们得先看一下java.lang.Comparable到底是个什么鬼。


    我们发现他是个接口,不是类;


    其实到这里我相信大家都猜到了,问题就是Comparable接口中的方法无法比较两个Student对象。所以在这我要重写compareTo()方法!!!
    TreeSet集合中对象都需要具备可比性。

    添加的代码如下:

    public int compareTo(Object obj) {//重写compareTo方法。
               if(!(obj instanceof Student))
                    throw new RuntimeException("not a Student.");
               Student st = (Student)obj;
               System.out.println(this.name+"....compare with..."+st.name);
               //当此对象大于指定对象时,返回1(正数就可以);
               //当此对象等于指定对象时,返回0;
               //当此对象大于指定对象时,返回-1(负数就可以);
               if(this.number>st.number)
                    return 1;
               if(this.number==st.number)
                    return 0;
               return -1;
         }
         public String getName() {
               return name;
         }
         public int getNumber() {
               return number;
         }
    }
    

    运行结果:


    说明,代码还不够完善;为了让它知道学号相同并不是同一个对象,并且当学号相同的时候,再根据名字的ASII的值来排序。我们改进为:

    public int compareTo(Object obj) {//重写compareTo方法。
               if(!(obj instanceof Student))
                    throw new RuntimeException("not a Student.");
               Student st = (Student)obj;
               System.out.println(this.name+"....compare with..."+st.name);
               //当此对象大于指定对象时,返回1(正数就可以);
               //当此对象等于指定对象时,返回0;
               //当此对象大于指定对象时,返回1(负数就可以);
               if(this.number>st.number)
                    return 1;
               if(this.number==st.number)
                    //String类也实现了Comparable接口。
                    return this.name.compareTo(st.name);
               return -1;
         }
    

    运行结果:


    好了大功告成!
    TreeSet底层的数据结构:

    添加元素时,就是在画二叉树;
    取元素时,遵循数据结构中以左中右的方式读取数据。

    现在:如何实现怎么存进去就怎么取出来?

    很简单:只要重写compareTo方法事,只返回正数或者负数;原理就是:compareTo方法返回负数就存在根元素的左边,如果返回负数就存在根元素的右边。
    TreeSet保证元素的唯一性的方法:return 0;

    总结:

    TreeSet排序的方式就是通过继承Comparable接口,重写compareTo方法。

    问题:

    • 上面我们是通过让元素具有比较性,来实现TreeSet集合对象的排序的。
    • 下面我们通过给集合对象增加比较性,来让TreeSet集合对象按照名字的顺序排序。

    做法:

    • 我们在不改变上面代码的基础上,添加比较器Comparetor接口来完成排序;
    • 先创建一个类,用这个类实现Comparetor接口,并重写里面的compare(T o1, T o2)方法,
    • 使其优先比较名字,名字相同再比较学号。
    • 然后在TreeSet集合定义时,将Comparetor对象作为参数传递给集合对象;这样集合对象就有比较性了!

    先查看相关文档:



    我们也看一下TreeSet的构造方法有哪些?


    接下就要看代码了:

    import java.util.*
    //定义Student类型
    class Student implements Comparable {//继承Comparable接口
         private String name;
         private int number;
         Student(String n, int nu){
               this.name = n;
               this.number = nu;
         }
         public int compareTo(Object obj) {//重写compareTo方法。
               if(!(obj instanceof Student))
                    throw new RuntimeException("not a Student.");
               Student st = (Student)obj;
               System.out.println(this.name+"....compare with..."+st.name);
               //当此对象大于指定对象时,返回1(正数就可以);
               //当此对象等于指定对象时,返回0;
               //当此对象大于指定对象时,返回1(负数就可以);
               if(this.number>st.number)
                    return 1;
               if(this.number==st.number)
                    //String类也实现了Comparable接口。
                    return this.name.compareTo(st.name);
               return -1;
         }
         public String getName() {
               return name;
         }
         public int getNumber() {
               return number;
         }
    }
    class treeSetStudent {
         public static void main(String[] args) {
               TreeSet ts = new TreeSet(new myCompare()); //定义TreeSet集合来存储Student类型对象。
               //TreeSet专门针对比较器的使用有一个构造方法,参数就是Comparator接口实现的对象。
               //如果一个程序中元素和几何对象都具有比较性,那么优先使用集合的比较器!
               ts.add(new Student("tom01",12));
               ts.add(new Student("tom07",22));
               ts.add(new Student("tom07",24));
               ts.add(new Student("tom09",12));
               Iterator it = ts.iterator();
               while(it.hasNext()) {
                    Student st = (Student)it.next();
                    System.out.println(st.getName()+"....."+st.getNumber());
               }
         }
    }
    class myCompare implements Comparator{
         public int compare(Object o1, Object o2) {
               Student s1 = (Student)o1;
               Student s2 = (Student)o2;
               int n = s1.getName().compareTo(s2.getName());
               if(n == 0) {
                    if(s1.getNumber()>s2.getNumber())
                         return 1;
                    if(s1.getNumber()==s2.getNumber())
                         return 0;
                    return -1;
                    //上面这段代码有点复杂,我们还可以用Integer整型对象调用compareTo()来代替。
                    //return new Integer(s1.getNumber()).compareTo(new Integer(s2.getNumber()))
                    //注意只要是类型对象都实现了compareTo()方法,他是java.lang报下面的方法。
               }
               if(n>0)
                    return 1;
               return -1;
         }
    }
    

    运行结果:

    总结:

    无论哪一种排序方法,底层的数据结构都是二叉树。**

    相关文章

      网友评论

          本文标题:集合框架Set----TreeSet

          本文链接:https://www.haomeiwen.com/subject/zbgtnftx.html