Set接口
Set特点
- 无序: 存取顺序不一致
- 无索引
- 元素不可重复
Set集合遍历方式
- 增强for
- 迭代器
Set集合常用子类
- HashSet
- LinkedSet
继承HashSet 能够保证存取顺序一致
HashSet的特点
- 无序 无索引 元素不可重复
- 底层结构: 哈希表
哈希表
- 数组和链表的结合体
哈希表特点
- 查询和增删都比较快
对象的哈希值
- 就是一个十进制的整数 是通过object类的hashCode()方法获得: int hashCode();
- 默认Object类的hashCode的方法返回的哈希值是该对象在内存中的地址值
- 哈希值的对象存储到哈希表的重要依据
哈希表的存储过程
哈希表的存储过程(存取原理):
- 调用对象的hashCode()方法, 获得要存储元素的哈希值
- 将哈希值与表的长度(即数组的长度)进行求余运算得到一个整数值, 该值就是新元素要存放的位置(即索引值)
- 如果索引值对应的位置上没有存储任何元素, 则直接将元素存储到该位置
- 如果索引值对应的位置上已经存储了元素, 则执行第3步
- 遍历该位置上所有旧元素, 依次比较每个旧元素的哈希值和新元素的哈希值是否相同
- 比较新旧元素的地址值是否相同
- 如果地址值相同则用新的元素替换旧的元素, 停止比较
- 如果地址值不同, 则新元素调用equals方法与旧元素比较内容是否相同
*如果返回true, 用新的元素替换旧的元素, 停止比较
*如果返回false, 则回到第3步继续遍历下一个旧元素
- 说明没有重复, 则将新元素存放到该位置上并让新元素记住之前该位置的元素
HashSet存储自定义对象
哈希表存储自定义对象
- 对象的哈希值默认的是调用父类Obejct类的hashCode方法获得的
- 父类的Object的hashCode方法返回值是对象在内存中地址值
- 所以只要对象的地址值不同, hashCode就会不同, 就算两个对象的属性值完全相同, 也不会判定为重复元素
自定义对象重写hashCode和equals方法
- 重写自定义对象的hashCode方法
尽可能让不同的属性值产生不同的哈希值, 这样就不用调用equals方法去比较属性, 效率较高
小结
当使用HashSet存储自定义类型, 如果没有重写该类的hashCode与equals方法, 则判断是否重复的依据时根据对象的地址值, 如果想通过内容比较元素是否相同, 需要重写该类的hashCode与equals方法