Set常用子类特点

时间:2022-07-23 02:01:41

HashSet:       重写   hashCode和equals方法                                  
      特点:无序,唯一
      底层结构是:
        哈希表:元素为链表的数组。综合了链表和数组的好处
      add方法:底层实际是依赖于HashCode()和equals()方法

HashSet实际用的是HashMap
public HashSet() {
map = new HashMap<>();
}

案例-HashSet存储自定义对象

出现问题:
   重复的元素也被添加了,不能保证元素唯一性

原因:自定义类没有重写HashCode和equals方法;

分析:
    (1) 默认继承Object类的HashCode和equals方法,而Object的HashCode值是通过对象
        的内部地址值转换为一个整数得到的,不同的对象的地址值不同,进而可以知道转换后
        的HashCode值也不可能相同。HashCode值不同就当作不是重复的元素而添加了。
   (2)equals方法默认也是比较地址值,如果不重写equals方法,那么不同的对象
        比较的结果也一定就是false;将会当作不是重复元素而添加了

解决:重写自定义类的HashCode和equals方法

思考:重写HashCode(),那么HashCode值跟什么有关系呢?
      答: 和对象的成员变量值有关系

重写HashCode方法:
      就将对象的成员变量值相加:
             基本类型:直接相加
            引用类型:就加哈希值

// return name.hashCode()+age;
     // 代码优化如下
     return name.hashCode()+age*31;

注意:判断是否是重复元素步骤:
        1-先比较HashCode值:
               1-1:如果HashCode值不同:直接添加
               1-2:如果HashCode值相同:
                    1-2-1:继续判断equals方法:
                                  返回false:添加元素
                                   返回true:放弃添加

对于hashCode和equals方法的理解:(新华字典: 即使是在同一页了,也有可能不是同一个元素)
        同一页:hashCode值
        同一页中同一个元素:hashCode值相同情况下,还要继续采用equals方法判断

二、LinkedHashSet:
      底层数据结构是:链表和哈希表
      链表保证元素有序
      哈希表保证元素唯一

三、TreeSet:

(1)实现Comparable自然排序接口,重写compareTo方法

(2)实现Comparator比较器排序接口,重写compare方法

排序方式:以构造函数确定排序方式
    A 无参构造:自然排序
   class Student implements Comparable<Student>{
       @Override
      public int compareTo(Student s){
       //按年龄排序
       int num=this.age-s.age;
       //隐含条件,年龄相同时,应该继续比较姓名
       int num2=num==0?this.name.compareTo(s.name):num;
       return num2;
      }
  }

B 有参构造:比较器排序 将自定义的比较器类对象作为构造方法的参数
    class MyComparator implements Comparator<Student>{
        @Override
       public int compare(Student s1,Student s2){
          int num=(int)(stu2.getTotal()-stu1.getTotal());
          int num2=num==0?stu1.getName().compareTo(stu2.getName()):num;
          return num2;
        }
    }
   TreeSet<Student> ts=new TreeSet<Student>(new MyComparator());

---------------------------------------------
字符串的比较
int compareTo(String str):