zoukankan      html  css  js  c++  java
  • 集合TreeSet的使用

      集合中的TreeSet是集合体系结构中的底层实现,是Collection的孙子,Set的儿子。TreeSet除拥有父接口的特点外,还有其自身的特点。下面就看看TreeSet的排序是怎么实现的。从它的构造方法看,提供了无参和带参两种。
      常用到的两个构造:
      无参构造  public TreeSet()
        
    构造一个新的空set,该set根据其元素的自然顺序进行排序。插入该set的所有元素都必须实现Comparable接口。
      带参构造  public TreeSet(Comparator<? super E> comparator)
        构造一个新的空TreeSet,它根据指定比较器进行排序。
      API文档里面已经描述的很清楚,要实现排序,要么实现Comparable接口,要么指定比较器Comparator。接下来就分别用两种方式来实现这个过程。
      描述一个Person类。拥有成员:name、age、有参、无参构造、getters、setters。

    package cn.dolphin;
    
    public class Person {
        private String name;
        private int age;
        public Person() {super();}
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    }

    第一种方式:
      使用有参构造,传递Comparator比较器。而Comparator是接口,所以没有对象,这时传递的就是实现了Comparator接口的子类的对象,而如果这个对象只用到一次又可以写成匿名内部类,于是就有了下面的代码。

    package cn.dolphin;
    
    import java.util.Comparator;
    import java.util.TreeSet;
    
    public class TreeSetDemo {
        public static void main(String[] args) {
            // 创建TreeSet对象,用来存储Person类型对象。
            TreeSet<Person> ts = new TreeSet<>(new Comparator<Person>() {
                @Override
                public int compare(Person o1, Person o2) {
                    int num1 = o1.getName().length() - o2.getName().length();
                    int num2 = num1 == 0 ? o1.getName().compareTo(o2.getName()) : num1;
                    int num3 = num2 == 0 ? o1.getAge() - o2.getAge() : num2;
                    return num3;
                }
            });
            // 创建Person对象并添加到ts集合。
            ts.add(new Person("aidengbao", 30));
            ts.add(new Person("bosideng", 21));
            ts.add(new Person("yichun", 18));
            ts.add(new Person("yichun", 18));
            for (Person s : ts) {
                System.out.println(s.getName() + ":" + s.getAge());
            }
        }
    }

    当然也可不写成匿名内部类,只是这样就必须得定义一个类来实现Comparator接口,于是用下面的代码:

    package cn.dolphin;
    
    import java.util.Comparator;
    
    public class ComparatorImplements implements Comparator<Person>{
        @Override
        public int compare(Person o1, Person o2) {
            //主要条件,按照Person的姓名长度排序,如不相同,则添加到集合。
            int num1 = o1.getName().length() - o2.getName().length();
            //如果姓名长度一样,再比较姓名是否相同。如不相同,则添加到集合。
            int num2 = num1 == 0 ? o1.getName().compareTo(o2.getName()) : num1;
            //如果姓名也相同,再比较年龄是不是相同,如果相同,则不添加到集合,保证数据的唯一。
            int num3 = num2 == 0 ? o1.getAge() - o2.getAge() : num2;
            return num3;
        }
    }

    这样,有了ComparatorImplements类实现Comparator接口后,就可以用多态的方式创建ComparatorImplements的对象传递给TreeSet。接着看代码:

    package cn.dolphin;
    
    import java.util.Comparator;
    import java.util.TreeSet;
    
    public class TreeSetDemo {
        public static void main(String[] args) {
            // 创建TreeSet对象,用来存储Person类型对象。
            Comparator<Person> ci = new ComparatorImplements();
            TreeSet<Person> ts = new TreeSet<>(ci);
            // 创建Person对象并添加到ts集合。
            ts.add(new Person("aidengbao", 30));
            ts.add(new Person("bosideng", 21));
            ts.add(new Person("yichun", 18));
            ts.add(new Person("yichun", 18));
            for (Person s : ts) {
                System.out.println(s.getName() + ":" + s.getAge());
            }
        }
    }

    通过上面的代码,明显看到使用匿名内部类的好处就是简单方便,接下来,再看看用无参构造的实现。
    第二种方式:
      使用无参构造,Person类自己实现Comparable接口。

    package cn.dolphin;
    
    public class Person implements Comparable<Person>{
        private String name;
        private int age;
        public Person() {super();}
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        @Override
        public int compareTo(Person o) {
            int num1 = this.name.length() - o.name.length();
            int num2 = num1 == 0 ? this.name.compareTo(o.name) : num1;
            int num3 = num2 == 0 ? this.age - o.age : num2;
            return num3;
        }
    }

    好像看起来这样要好一点点,因为在这里可以直接使用name和age成员变量,而上面只能过过getName()和getAge()来获取,因为定义的成员在开发中可能都是私有的。Person类实现了Comparable接口,就可以使用无参的构造来对对象进行唯一性判断和对集合排序。

    package cn.dolphin;
    
    import java.util.TreeSet;
    
    public class TreeSetDemo {
        public static void main(String[] args) {
            // 创建TreeSet对象,用来存储Person类型对象。
            TreeSet<Person> ts = new TreeSet<>();
            // 创建Person对象并添加到ts集合。
            ts.add(new Person("aidengbao", 30));
            ts.add(new Person("bosideng", 21));
            ts.add(new Person("yichun", 18));
            ts.add(new Person("yichun", 18));
            for (Person s : ts) {
                System.out.println(s.getName() + ":" + s.getAge());
            }
        }
    }

    虽然写了这么长,但是TreeSet并不是多么重要,用到并不多,所以也就当个了解内容吧,不过多知道点儿总归不是坏事儿。

  • 相关阅读:
    jquery实现选项卡(两句即可实现)
    常用特效积累
    jquery学习笔记
    idong常用js总结
    织梦添加幻灯片的方法
    LeetCode "Copy List with Random Pointer"
    LeetCode "Remove Nth Node From End of List"
    LeetCode "Sqrt(x)"
    LeetCode "Construct Binary Tree from Inorder and Postorder Traversal"
    LeetCode "Construct Binary Tree from Preorder and Inorder Traversal"
  • 原文地址:https://www.cnblogs.com/magics/p/3633653.html
Copyright © 2011-2022 走看看