美文网首页
No. 4.2 TreeSet有序Set集合

No. 4.2 TreeSet有序Set集合

作者: 醒着的码者 | 来源:发表于2016-04-10 22:21 被阅读182次

    说TreeSet是有序集合,更通俗的解释应该是TreeSet提供了对存储元素的比较方法;

    • TreeSet(Comparator<? super E> comparator)
      上面的构造方法为TreeSet特有的方法;可以看到构造函数中传入了一个Comparator(比较器);这个比较器默认为自然顺序排列;但是我们可以自定义一个类实现这个接口,并覆写其中的compare方法来实现自定义排序;
    • 如果TreeSet存放的是Integer对象,默认排序方法为 小到大;
    • 如果TreeSet存放的是String对象,默认排序方法为字符串首字母开始比较,按Unicode值大小排序;
    • 如果TreeSet存放的是自定义类;如果不指定指定比较器,那么就会报异常;

    TreeSet存储元素的简单实例:

        TreeSet<Integer> ts = new TreeSet<>();
        
        ts.add(1);
        ts.add(3);
        ts.add(2);
        
        for(Integer i : ts){
            System.out.println(i);
        }
    

    输出结果为 1,2,3;由此可见Treeset内部实现了按元素的自然顺序排序的方法(由小到大);

    实现Integer对象由大到小的自定义排序:

    我们自定义一个comparator类,实现comparator接口,并把这个类传入TreeSet的构造参数中;

    实现步骤:
    1.自定义类实现comparator接口;
    2.覆写compare方法,实现自定义排序方法;
    3.创建TreeSet对象,并传入上述自定义类;

    public  class MyComparator implements Comparator<Object> {
    @Override
    public int compare(Object o1, Object o2) {
        Integer x = (Integer)o1;
        Integer y = (Integer)o2;
        //compare方法返回0代表,两者值相同;返回1代表前者大于后者,返回-1代表前者小于后者
        return x == y ? 0 :((x < y) ? 1 : -1);
      }
    }
    

    public class TreeSetDemo {
    
    public static void main(String[] args) {
        TreeSet<Integer> ts = new TreeSet<>(new MyComparator());
        
        ts.add(1);
        ts.add(3);
        ts.add(2);
        
        
        Iterator<Integer> it = ts.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
      }
    }
    

    实现自定义类TreeSet存储的两个方式:

    方式1:自定义类 实现Comaparable接口!!!这里不是比较器所实现的Comparator接口。注意区别:

    我们将上节的Person类是实现该接口:功能是实现为首先按照name排序,如果名字相同,在按照Id大小排序;

    public class Person implements Comparable<Person>{
      private Integer Id;
      private String name;
    
      public Person(int Id , String name){
        this.Id = Id;
        this.name = name;
      }
    
      @Override
      public String toString() {
        String str = "[" + " id: " + Id + ",name: " + name +"]";
        return str;
      }
    
      @Override
      public int compareTo(Person o) {
        Person p = o;
        int temp = this.name.compareTo(p.name);
        int result = temp == 0 ? (this.Id.compareTo(p.Id)) : temp;
        return result;
      }
     }
    

    主函数实现:

    public class TreeSetDemo {
    
    public static void main(String[] args) {
        TreeSet<Person> ts = new TreeSet<>();
        Person p1 = new Person(3, "lili");
        Person p2 = new Person(2, "lili");
        Person p3 = new Person(1, "abc");
        
        ts.add(p1);
        ts.add(p2);
        ts.add(p3);
        
        for(Object person : ts){
            System.out.println(person);
        }
    
    }
    }
    

    方式2: 自定义Comparator实现Comparator接口并在初始化TreeSet的时候传入:

    比较器实现方法:

    public  class MyComparator implements Comparator<Object> {
      @Override
      public int compare(Object o1, Object o2) {
        Person p1 = (Person)o1;
        Person p2 = (Person)o2;
        int temp = p1.getName().compareTo(p2.getName());
        int result = temp == 0 ? (p1.getId().compareTo(p2.getId())) : temp;
        return result;
      }
    }
    

    Person类实现方法:

    public class Person {
    private Integer Id;
    private String name;
    
    public Person(int Id , String name){
        this.Id = Id;
        this.name = name;
    }
    
    @Override
    public String toString() {
        String str = "[" + " id: " + Id + ",name: " + name +"]";
        return str;
    }
    
    public Integer getId() {
        return Id;
    }
    
    public void setId(Integer id) {
        Id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    }
    

    主函数实现方法:

      public class TreeSetDemo {
    
    public static void main(String[] args) {
        TreeSet<Person> ts = new TreeSet<>(new MyComparator());
        Person p1 = new Person(3, "lili");
        Person p2 = new Person(2, "lili");
        Person p3 = new Person(1, "abc");
        
        ts.add(p1);
        ts.add(p2);
        ts.add(p3);
        
        for(Object person : ts){
            System.out.println(person);
        }
    
    }
    
    • 相比于方法1,方法2更实用一些,因为在定义一个类的时候我们还不知道他要存储在什么集合中,所以我们没有必要每个类都实现Comparable接口;
      在需要在TreeSet集合中存储的时候只需要在定义个比较器传入构造参数即可;

    相关文章

      网友评论

          本文标题:No. 4.2 TreeSet有序Set集合

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