• Java基础——TreeSet


    TreeSet是SortedSet接口的实现类,Sorted的英文意思是分类的;选择的。

    TreeSet可以确保集合元素处于排序状态。与HashSet集合相比,TreeSet还提供了如下几个额外方法:

    方法名称 解释
    Comparator comparator(); 如果TreeSet采用了定制排序,则该方法返回定制排序所使用Comparator;如果TreeSet采用了自然排序,则返回null;
    Object first(); 返回集合中的第一个元素;
    Object last(); 返回集合中的最后一个元素;
    Object lower(Object o); 返回集合中位于指定元素之前的元素(即小于指定元素的最大元素,参考元素不需要是TreeSet集合里的元素);
    Object higher(Object o); 返回集合中位于指定元素之后的元素(即大于指定元素的最小元素,参考元素不需要是TreeSet集合里的元素);
    SortedSet subSet(Object fromElement,Object toElement); 返回此Set的子集合,返回从fromElement,Object (包含到)toElement(不包含);
    SortedSet headSet(Object toElement); 返回此Set的子集,由小于toElement的元素组成;
    SortedSet tailSet(Object fromElement); 返回此Set的子集,由大于或等于fromElement的元素组成;

     1 import java.util.Set;
     2 import java.util.TreeSet;
     3 
     4 public class TreeS {
     5     public static void main(String[] args) {
     6         Set<String> set = new TreeSet<String>();// 定义了泛型
     7         set.add("Java");
     8         set.add("Js");
     9         set.add("PHP");
    10         set.add("C#");
    11         set.add("C++");
    12         set.add(".Net");
    13         // 打印集合
    14         System.out.println(set);
    15 
    16         // 输出集合的容量
    17         System.out.println(set.size());
    18 
    19         // 如果此 set 不包含任何元素,则返回 true
    20         System.out.println(set.isEmpty());
    21 
    22     }
    23 }
    output:
    [.Net, C#, C++, Java, Js, PHP]
    6
    false

    与HashSet集合采用通过hash算法来决定元素的存储位置不同,TreeSet采用红黑树的数据结构来存储集合元素。
    TreeSet支持两只排序方法:自然排序与自定义。

    一、自然排序:

    TreeSet会调用集合元素的compareTo(Object o)方法来比较元素之间的大小关系,然后将集合元素按升序排列,这种方式是自然排序。
    Java提供了一个Comparable接口,该接口定义一个compareTo(Object o)方法,该方法返回一个整数值,实现该接口的类必须实现该方法,实现该接口的类的对象就可以比较大小。

    例一&例二:

     1 import java.util.TreeSet;
     2 
     3 public class T {
     4     public static void main(String[] args) {
     5 
     6         // 例一:数字排序
     7         /*
     8          * TreeSet a = new TreeSet();
     9          *  a.add(10); 
    10          *  a.add(55); 
    11          *  a.add(4); 
    12          *  a.add(6);
    13          *  a.add(-1); 
    14          *  a.add(-77); 
    15          *  a.add(0);
    16          * 
    17          * System.out.println(a);//打印:[-77, -1, 0, 4, 6, 10, 55]
    18          */
    19 
    20         //例二:字母排序
    21         TreeSet ts=new TreeSet();
    22         ts.add("b");
    23         ts.add("ee");
    24         ts.add("d");
    25         ts.add("abc");
    26         ts.add("ca");
    27         
    28     /*    abc
    29         b
    30         c
    31         ca
    32         d
    33         ee*/
    34         
    35         System.out.println(ts); //[abc, b, ca, d, ee]
    36     }
    37 }

    例三:(下面这个例子没有写具体的比较规则。)

     1 import java.util.Set;
     2 import java.util.TreeSet;
     3 
     4 class TreeS implements Comparable<Object> {
     5 
     6     int score;
     7 
     8     public TreeS(int score) {
     9         this.score = score;
    10     }
    11 
    12     public int compareTo(Object o) {
    13         return 1;
    14     }
    15 
    16     public boolean equals(Object obj) {
    17         return true;
    18     }
    19 
    20     public static void main(String[] args) {
    21         Set<Object> set = new TreeSet<Object>();
    22         
    23         // 计划在添加两个对象
    24         set.add(new TreeS(77));
    25         set.add(new TreeS(7));
    26         
    27         System.out.println(set);
    28 
    29     }
    30 }
    output:
    [TreeS@67064, TreeS@bcda2d]

    例四:(这个例子为了引出自定义计较方法,其实已经用上一点了)

    判断两个对象的是否相等的参照标准如下:

     1 import java.util.Set;
     2 import java.util.TreeSet;
     3 
     4 class TreeS implements Comparable<Object> {
     5 
     6     int score;
     7 
     8     public TreeS(int score) {
     9         this.score = score;
    10     }
    11 
    12     public int compareTo(Object o) {
    13         TreeS d=(TreeS)o;//强制类型转换
    14         return this.score>d.score? 1:this.score<d.score? -1:0;
    15         }
    16 
    17     public boolean equals(Object obj) {
    18         if(this==obj){
    19             return true;
    20         }else if(obj!=null&&obj.getClass()==TreeS.class){
    21             TreeS d=(TreeS)obj;
    22             return d.score==this.score;
    23         }
    24         return false;
    25     }
    26 
    27     public static void main(String[] args) {
    28         Set<Object> set = new TreeSet<Object>();
    29         
    30         // 计划在添加两个对象
    31         set.add(new TreeS(77));
    32         set.add(new TreeS(77));//没有被打印
    33         set.add(new TreeS(20));
    34         set.add(new TreeS(3));
    35         set.add(new TreeS(44));
    36         set.add(new TreeS(44));//没有被打印
    37         set.add(new TreeS(6));
    38         set.add(new TreeS(-11));
    39         set.add(new TreeS(9));
    40         set.add(new TreeS(0));
    41         
    42         System.out.println(set);
    43 
    44     }
    45 }
    output:
    [TreeS@97d01f, TreeS@e0a386, TreeS@feb48, TreeS@11ff436, TreeS@da3a1e, TreeS@11dba45, TreeS@b03be0, TreeS@2af081]

    注意:

    与HashSet类似的是,如果TreeSet中包含了可变对象,当可变对象的示例变量被修改时,TreeSet在处理这些对象时将非常复杂,而且容易出错。为了让程序更加健壮,推荐不要修改放入HashSet和TreeSet集合中元素的关键实例变量。

    二、自定义排序

    TessSet 的自然排序是根据集合元素的大小,TreeSet将它们以升序排列。如果需要实现定制排序,例如以降序排列,则可通过Comparator接口的帮助。

    例一:

    //使用TreeSet对学生考试成绩排序
    //怎么做?  
    //1 让对象实现 Comparable 接口    
    //2 然后重写compareTo 方法  
    //interface Comparable<T>  Comparable 接口
    //int compareTo(T o)  Comparable接口中的方法 返回负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。
    public class Student implements Comparable<Object>{
        int age;
        int score;
        String name;
        
        @Override //在自己重写的时候,先写上它,可以帮你报错
        public String toString(){
            return this.name+":"+this.age+":"+this.score;
        }
        
        public Student(int age,int score,String name){
            this.name=name;
            this.age=age;
            this.score=score;
            }
            
            @Override
            //用返回值是正数、负数或者零来判断大小
            public int compareTo(Object obj){
                
                if(!(obj instanceof Student)){
                    throw new RuntimeException("输入的不是本类对象,请重新输入");
                }
                Student stu=(Student)obj;
                if(this.score>stu.score){
                    return 1; //设置为是正数就行了
                }else if(this.score<stu.score){
                    return -1;
                }else {
                    //设置如果相等的例子,上面有个例子,相等的情况会丢失数据,这里要考虑到
                    int result=this.name.compareTo(stu.name);
                    if(result==0)
                        return 1;
                    return result;
                }
                
            }
        }

    测试类:

    import java.util.Iterator;
    import java.util.Set;
    import java.util.TreeSet;
    
    public class Test {
        public static void main(String[] args) {
            Set<Student> treeSet = new TreeSet<Student>();
    
            treeSet.add(new Student(11, 80, "李平"));
            treeSet.add(new Student(23, 40, "王芳"));
            treeSet.add(new Student(10, 60, "赵磊"));
            treeSet.add(new Student(12, 40, "王小二"));
            treeSet.add(new Student(10, 60, "马苗"));
            treeSet.add(new Student(18, 60, "马苗"));
            treeSet.add(new Student(25, 70, "姜浩"));
    
            Iterator<Student> it = treeSet.iterator();
            while (it.hasNext()) {
                Student stu = (Student) it.next();
                System.out.println(stu);
            }
    
        }
    }

    例二:

    //例子 往 treeset中放字符串,按字符串长度排序
                    
            class MyComparator implements Comparator{
                @Override
                public int compare(Object o1, Object o2) {
                    Student stu1=(Student)o1;
                    Student stu2=(Student)o2;
                    
                    if(stu1.score>stu2.score){
                        return 10;  //只要是正为数就行
                    }
                    else if(stu1.score<stu2.score){
                        return -10;
                    }
                    else{
                        //return  0;
                        return stu1.name.compareTo(stu2.name);
                    }
                }
            }
            
            main 方法中 
            
            Set set=new TreeSet(new StrLenComparator());
            set.add("cc");
            set.add("b");
            set.add("dddddddd");
            set.add("kkkkkkkkkkk");
            set.add("v");
            set.add("ee");
            set.add("sssss");
            
            Iterator it2=set.iterator();
            while(it2.hasNext()){
                System.out.println(it2.next());
            }

    例三:

    附: 使用匿名类
        Set set=new TreeSet(new Comparator() {  //这里使用了匿名类
                @Override
                public int compare(Object o1, Object o2) {
                    String str1=(String)o1;
                    String str2=(String)o2;
                    
                    if(str1.length()>str2.length()){
                        return 1;
                    }
                    else if(str1.length()<str2.length()){
                        return -1;
                    }
                    else{
                        //return 0;
                        return 1;  //如果相等,反回1的目的,是怕丢数据
                    }
                }
            }

    总结:

    TreeSet是依靠TreeMap来实现的,所以是根据实现的Compareble接口或Comparator接口来判断元素是否重复,其排序与TreeMap一样。

  • 相关阅读:
    Atitit opencv3.0  3.1 3.2 新特性attilax总结
    Atitit html5.1 新特性attilax总结
    Atitit http2 新特性
    Atitit 大龄软件工程师的出路attilax总结
    Atitit 软件项目系统托盘图标解决方案
    Atitit js canvas的图像处理类库attilax总结与事业
    Atitit 切入一个领域的方法总结 attilax这里,机器学习为例子
    css知多少(8)——float上篇
    css知多少(7)——盒子模型
    css知多少(6)——选择器的优先级
  • 原文地址:https://www.cnblogs.com/1693977889zz/p/7094365.html
Copyright © 2020-2023  润新知