栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

TreeSet集合的使用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

TreeSet集合的使用

TreeSet集合

目录

TreeSet集合

自然排序:Comparable接口的使用

案例分析

总结

比较器排序Comparator的使用

两种方法比较


public class TreeSet
extends AbstractSet
implements NavigableSet, Cloneable, Serializable
  • 元素有序,但这里的顺序不是元素的存储与取出顺序,而是按照一定规则进行的排序,具体排序方式取决于构造方法 :TreeSet() : 无参构造,根据其元素的自然排序进行排序

    TreeSet(Comparator comparator) : 根据指定的比较器进行排序

  • 没有带索引的方法,所以不能使用普通for循环

  • 是Set集合,所以不包含重复元素

import java.util.TreeSet;
​
public class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet ts = new TreeSet();        //<>中不能为基本数据类型
​
        ts.add(10);
        ts.add(40);
        ts.add(60);
        ts.add(20);
​
        ts.add(20);
​
        for(Integer i : ts){
            System.out.println(i);
        }
    }
}
​
​
//  自然排序
10
20
40
60
​

自然排序:Comparable接口的使用
  • 该接口对实现它的每个类的对象强加一个整体排序。 这个排序被称为类的自然排序 ,类的compareTo方法被称为其自然比较方法

只有唯一方法:

int compareTo(T o)
将此对象与指定的对象进行比较以进行排序。 返回一个负整数,零或正整数,因为该对象小于,等于或大于指定对象。 

案例分析

问题

//学生类,没有实现Comparable接口
public class Student {
    private String name;
    private int age;
​
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
​
    public Student() {
    }
​
    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;
    }
​
}
//demo,运行会报错
//未覆盖java.lang.Comparable中的抽象方法compareTo(com.Set.TreeSetD.Student)
​
import java.util.TreeSet;
public class demo {
    public static void main(String[] args) {
        TreeSet ts = new TreeSet();
​
        Student s1 = new Student("林青霞",33);
        Student s2 = new Student("张曼玉",23);
        Student s3 = new Student("眼红和",14);
        Student s4 = new Student("金城武",32);
​
​
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
​
        for(Student s : ts){
            System.out.println(s.getName()+","+s.getAge());
        }
    }
}

解决方法

  • 让学生类实现Comparable接口

  • 让学生类重写CompareTo方法

public class Student implements Comparable{
  ...
  @Override
    public int compareTo(Student s) {
        return 0;
    }
}

执行dome类结果是:

林青霞,33 //只有一个元素,原因是在重写后默认比较规则中,返回值是0,是0则认为添加来的元素跟比较的是一样的

返回值改为恒正数

再次重写

public class Student implements Comparable{
  ...
  @Override
    public int compareTo(Student s) {
        return 1;
    }
}

执行dome类结果是:

林青霞,33
张曼玉,23
眼红和,14
金城武,32   //跟存入顺序相同

返回值改为恒负数

再次重写

public class Student implements Comparable{
  ...
  @Override
    public int compareTo(Student s) {
        return -1;
    }
}

执行dome类结果是:

金城武,32
眼红和,14
张曼玉,23
林青霞,33   //跟存入顺序相反

按需求改写为 按年龄排序

再次重写

public class Student implements Comparable{
  ...
  @Override
    public int compareTo(Student s) {
        return this.getAge()-s.getAge();
    }
}

执行dome类结果是:

眼红和,14
张曼玉,23
金城武,32
林青霞,33  //跟年龄大小顺序保持一致

bug

import java.util.TreeSet;
public class demo {
    public static void main(String[] args) {
        TreeSet ts = new TreeSet();
​
        Student s1 = new Student("林青霞",33);
        Student s2 = new Student("张曼玉",23);
        Student s3 = new Student("眼红和",14);
        Student s4 = new Student("金城武",32);
​
        Student s5 = new Student("胡一菲",32);
​
​
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
​
        for(Student s : ts){
            System.out.println(s.getName()+","+s.getAge());
        }
    }
}
​
//
        Student s4 = new Student("金城武",32);
​
        Student s5 = new Student("胡一菲",32);
        
       年龄相同则认为他们俩为同一个对象,就不存入此集合

解决办法:

@Override
public int compareTo(Student s) {
    int num = this.age-s.age;
    int num2 = num == 0 ? this.name.compareTo(s.name):num; 
    //String类可以直接使用该方法,因为String类实现了Comparable接口并且重写了该方法
    return num2;
}

执行dome类结果是:

眼红和,14
张曼玉,23
胡一菲,32
金城武,32
林青霞,33

总结
  • 用TreeSet集合存储自定义对象,无参构造方法使用自然排序会报错

  • 自然排序,就是让所属的类实现Comparable接口,重写CompareTo()方法

  • 重写方法时,一定要注意排序规则必须按照要求的主要次要条件进行

比较器排序Comparator的使用
public static void main(String[] args) {
    TreeSet ts = new TreeSet(new Comparator() {  //匿名内部类
        @Override
        public int compare(Student o1, Student o2) {      //在Comparator中重写compare方法
            int num = o1.getAge()- o2.getAge();
            int num2 = num == 0 ? o1.getName().compareTo(o2.getName()):num;    
            return num2;
        }
    });
​
​
    Student s1 = new Student("林青霞",33);
    Student s2 = new Student("张曼玉",23);
    Student s3 = new Student("眼红和",14);
    Student s4 = new Student("金城武",32);
​
    Student s5 = new Student("胡一菲",32);
​
​
    ts.add(s1);
    ts.add(s2);
    ts.add(s3);
    ts.add(s4);
    ts.add(s5);
​
    for(Student s : ts){
        System.out.println(s.getName()+","+s.getAge());
    }
}
​
//
眼红和,14
张曼玉,23
胡一菲,32
金城武,32
林青霞,33

两种方法比较
自然排序比较器排序
使用的接口或者类Comparable接口Comparator类(可实例化)
使用方法在TreeSet的无参构造中使用在TreeSet的有参构造中使用(匿名内部类)
重写的内容以及位置在Student(元素类型类)中实现Comparable接口并重写CompareTo方法直接在构造器的匿名内部类中重写Compare方法

使用TreeSet集合最需要注意的就是:
- 次要条件的分析

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/309878.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号