• 集合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并不是多么重要,用到并不多,所以也就当个了解内容吧,不过多知道点儿总归不是坏事儿。

  • 相关阅读:
    第一次离职
    代码人生
    Array.Sort()实现细节和效率
    步入正轨
    2013,冲刺、加油!!!
    Struts2 OGNL 字符串自定义转化对象细节
    Struts2 输入格式自动校验的一些注意事项
    MySQL 5.7.17 Windows安装和启动
    关于Hibernate 5 和 Hibernate 4 在创建SessionFactory的不同点分析(解决 org.hibernate.MappingException: Unknown entity: xx类报错问题)
    Struts2 OGNL 自动转换Date类型的一些注意事项
  • 原文地址:https://www.cnblogs.com/magics/p/3633653.html
Copyright © 2020-2023  润新知