zoukankan      html  css  js  c++  java
  • java set TreeSet详解

    TreeSet 是sortedSet的唯一实现类,正如SortedSet名字暗示,TreeSet可以让集合元素处在排好序的状态。

    与HashSet相比,TreeSet还额外提供了以下的方法(列出来,混个脸熟:)

    SortedSet subSet(Object  fromElement,Object toElement) :返回这个Set的子集合,范围从fromElement(包含)到toElement(不包含)

    SortedSet headSet(Object toElement):返回这个Set的子集合,范围小于toElement的子集合 

    SortedSet tailSet(Object fromElement):返回这个Set的子集合,范围大于或等于fromElement的子集合 

    Object first(): 返回这个Set第一个元素 

    Object last():返回这个Set最后一个元素

    Object lower(Object e):返回小于指定元素的集合里最大的那个元素 

    Object higher(Object e):返回大于指定元素的集合里最小的那个元素     

    【以上参考元素都不需要是集合里的

     总结一下,最后四个方法就是找到集合里的第一个,前一个,后一个,最后一个元素。同时前三个就是返回该集合的符合条件的子集合。

    package Test01;
    
    import java.util.TreeSet;
    
    public class TestTreeSet {
         
      public static void main(String[] args) {
        TreeSet num =new TreeSet();
        num.add(2);
    num.add(
    -2); num.add(10); num.add(9); System.out.println(num); //看出:不是按照添加的顺序来,是数字由小到大排序 System.out.println(num.first()); //看出:数字由小到大排序的第一个 System.out.println("9到12 之间的"+num.subSet(9, 12)); System.out.println("比8小的"+num.headSet(8)); System.out.println("比8大的"+num.tailSet(8)); } }

    与hashset采用hash算法决定元素的存储位置,TreeSet采用红黑树的数据结构(待跟进)来存储集合元素。那么他的排序规则是怎么的呢?

    自然排序(默认情况)。

           调用TreeSet的无参的构造器,并实现Comparable接口,实现里的 compareTo(Object obj)方法,来比较集合元素的大小,然后按照compareTo里的排序。

         该种方法注意:

    向TreeSet里添加元素时,只有第一个无须实现Comparable接口,后面的必须实现。(第二个及后面的会调用compareTo方法,与集合里的其他元素比较,要求了比较的两个元素都是一个类的实例,否则会ClassCastException)

    package Test01;
    import java.util.TreeSet;
     public class Foo implements Comparable{
        int num;
        public Foo(int num) {
            this.num =num;
        }
        public int getNum() {
            return num;
        }
        public void setNum(int num) {
            this.num = num;
        }
        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return "foo:"+this.getNum();
        }
        @Override
        public int compareTo(Object obj) {
            // TODO Auto-generated method stub
            if(obj instanceof Foo) {
                 Foo f    =  (Foo) obj;
                 if(this.num > f.getNum()) {
                     return 1;
                 }
                 if(this.num == f.getNum()) {
                     return 0;
                 }
                 else
                     return -1;
                 
            }
            else return 0;
             
        }
        public static void main(String[] args) {
            TreeSet<Foo> test = new TreeSet<>();
            test.add(new Foo(8));        test.add(new Foo(3));
            System.out.println(test);
        }
         
    } 

    下面的一些常用的类已经实现了Comparable接口,提供了比较大小的标准:

    BigDecimal

    character

    Boolean

    String

    Date Time

    对于TreeSet集合来说,判断两个对象是否相等的唯一标准 是compareTo(Object obj)返回0,是0 就相等,不是0就不等。就不会让相等的对象进入集合。

    举例

    (正确的结果)能够插入两个compare 不等于0但是equals为true的对象

    package Test01;
    
    import java.util.Comparator;
    import java.util.TreeSet;
    
    public class Comp implements Comparator<Foo>{
    
        @Override
        public int compare(Foo o1, Foo o2) {
              return 1;
         }
        
        @Override
        public boolean equals(Object obj) {
            // TODO Auto-generated method stub
            return true;
        }
    
        public  static void main(String[] args) {
            TreeSet<Foo> t = new TreeSet<>(new Comp());
            Foo f = new Foo(0);
            t.add(f);
            t.add(f);
            System.out.println(t);
            t.first().num =9;
            System.out.println(t);
            
        }
    }

     留意下注释的差别,(问题已解决)

    package Test01;
    
    import java.util.TreeSet;
    
    public class Test implements Comparable{
        int num;
        public Test(int num) {
            this.num=num;
        }
        public int getNum() {
        return num;
        }
        public void setNum(int num) {
            this.num = num;
        }
        @Override
        public boolean equals(Object obj) {
            // TODO Auto-generated method stub
            return true;
        }
        @Override
        public int compareTo(Object o) {
            // TODO Auto-generated method stub
            return 1;
        }
        public  static void main(String[] args) {
            TreeSet  t = new TreeSet();
            Test f = new Test(0);
            t.add(f);
           
            System.out.println("会把同一个对象但是compareTo返回1添加进TreeSet吗?"+ t.add(f));   //equals不是评价对象相等的标准,compareTo返回0才相等。返回true
            System.out.println(t);
            ((Test)(t.first())).num=9;   //修改第一个元素,下面一行发现最后一个元素也被改成了9
            
            System.out.println( ((Test)(t.last())).num);
        }
    
    }
     

    由正确的结果注意:TreeSet也是Set,equals结果注意保持和compareTo结果一致。因为如果compareTo 等于0,但是equals发现false,就和Set冲突。

    和hashset同样,讨论下,可变对象插入删除问题(留意注释部分)

    package Test01;
    
    import java.util.Iterator;
    import java.util.TreeSet;
    
    class mutClass implements Comparable{
        public int count;
        public  mutClass(int count) {
            this.count =count;
        }
        public  boolean equals(Object obj) {
            if(this == obj) {
                return true;
            }
            if(obj != null && obj.getClass() == mutClass.class) {
                mutClass m =(mutClass) obj;
                return this.count == m.count;
            }
            return false;
        }
        public  int hashcode() {
            return this.count;
        }
        public String toString() {
            return "试试mutClass[count=" + count + "]";
        }
        @Override
        public int compareTo(Object o) {
            // TODO Auto-generated method stub
            mutClass m = (mutClass) o;
            return count>m.count?1 :count<m.count?-1 :0;
        }
        
    }
    public class TestTreeSet {
       @SuppressWarnings("unchecked")
    public static void main(String[] args){
           TreeSet testHashSet =new TreeSet(); 
           mutClass a = new mutClass(3);
           mutClass b = new mutClass(1);
           mutClass c = new mutClass(-9);
           mutClass d = new mutClass(9);
           testHashSet.add(a);
           testHashSet.add(b);
           testHashSet.add(c);
           testHashSet.add(d);
            System.out.println("第一次"+testHashSet);
            ((mutClass)testHashSet.first()).count =20;
            System.out.println("第二次"+testHashSet);   //修改可变对象的实例变量,不会调整顺序
           ((mutClass)testHashSet.last()).count =1;   //修改可变对象的实例变量,不会调整顺序,且可能出现重复对象的情况
           System.out.println("第三次"+testHashSet);
           System.out.println(testHashSet.remove(new mutClass(1)));  //删除实例变量被修改的元素,应该删除失败,但是我删除成功了?
           System.out.println("第四次"+testHashSet);
    
        }
    }

     定制排序。

    自己写个比较器的类,传入TreeSet的有参数的构造器,这样往集合里add元素就能按照定制的顺序排序了。

    package Test01;
    
    import java.util.Comparator;
    import java.util.TreeSet;
    
    public class Comp implements Comparator<Foo>{
    
        @Override
        public int compare(Foo o1, Foo o2) {
            // TODO Auto-generated method stub
            if(o1.getNum()>o2.getNum()) {
                return 1;
            }
            if (o1.getNum() == o2.getNum()) {
                return 0;
            }
            else return -1;
         }
        public  static void main(String[] args) {
            TreeSet<Foo> t = new TreeSet<>(new Comp());
            t.add(new Foo(0));
            t.add(new Foo(-9));
            System.out.println(t);
        }
    }
  • 相关阅读:
    js引用类型赋值不改变原对象值
    VS2017启动实例调试(谷歌浏览器)闪退问题
    ext6时间控件(带时分秒)
    extjs列表中文件上传与下载(带有重命名操作)
    c# word(1) 向标签处添加文字
    关于页面加载后执行使用afterrender
    ExtJS,grid多选框列
    vue起手式
    Javascript诞生与历史
    markdown语法说明
  • 原文地址:https://www.cnblogs.com/yizhizhangBlog/p/9257892.html
Copyright © 2011-2022 走看看