HashSet方法和TreeSet方法基本相同

常用方法:

add() 增加 remove(); 删除 只能根据元素内容删除

HashSet(散列存放的子类)

无序: 跟放入顺序无关,结果也是无序的
元素不允许重复
跟TreeSet不同 放入元素 尽管没有实现比较器 也不会报错 但是没有实现查重规则
所以HashSet的查重规则(因为没有大小比较)不是比较器

那么HashSet的查重规则到底是什么呢?

先调用hashCode方法 再调用equals方法进行比较

HashSet集合再放入引用数据类型是 需要进行查重比较 查重的规则是
先调用hashCode方法 如果hashCode方法相等
则再去调用equals方法 进行各项属性的比较
如果hashCode方法不相等 则判定两个对象不相等
第一步:
hashCode:
什么是hashCode方法:在Object类中定义的,默认的功能是返回当前对象跟地址值相关的一串数据(无意义)
那么需要我们自己覆写,覆写要实现什么样子有意义的功能呢?
为什么HashSet集合在放入对象时 要先比较hashCode方法 再去比较equals方法呢?直接调用equals去比较对象是否相等不就好了么?
equals方法是对象和对象之间进行各项属性的比较 从而判断两个对象是否相等,所以效率非常低下

所以要先调用hashCode方法 进行非常效率的比较,
也就是先快速比较出两个对象是否相等,
一旦hashCode方法比较出两个对象不相等了,
那就不用去调用equals方法了 提高了效率
* 如果hashCode无法判断出这两个对象是否相等
那么就要请出我们的大哥equals方法 进行各项属性的比较了

hashCode方法到底是什么代码?应该实现什么功能呢?
实现根据各项属性值 动态计算出一个哈希码
例如: age5+name.length3
先进行每一个对象的哈希码比较,一旦hashCode返回值 也就是哈希码不相等 那么两个对象必然不相等,那么比较出结果,
不需要再调用equals方法
如果hashCode返回值也就是哈希码相等,并不能说明 两个对象一定相等,因为不同的数值经过同样的算法有可能算出同样结果
所以这个时候就要用equals方法 进行各项属性的比较 看看是否每一个属性都相等

第二步:
equasl:
进行各项属性的详细比较
先比较hashCode方法是为了提高比较效率
后用equals比较 是为了提高比较的准确率

那么我们如果不覆写这两个方法 HashSet不会报错 ,但是也没有实现查重 为什么?
因为如果我们没覆写,那么调用是父类Object的hashCode方法,而Object的hashCode方法返回地址值
只要是新创建出来的对象 地址必然不相等
那么如果地址相等了 hashSet还会去调用equals方法,那么此时我们依然没覆写,调用的是Obejct类的
Object类的equals是进行==比较 比较地址
* 所以我们必须进行两个方法的合理覆写,定义我们想要比较的规则
image.png
hashCode源码 : image.png

* TreeSet和HashSet的区别

  • 共同点:
    无序:跟元素的放入顺序无关
    没有角标
    遍历方式 :1.增强for循环遍历 2.迭代器遍历
    TreeSet:
    结果是排序的
    排序规则是比较器
    不允许出现null值
    HashSet:
    结果是无序的
    查重规则是hashCode和equals
    可以有null值 多个null视为重复 只能出现一个