JavaSE进阶

11.5 Set接口

  • Set接口是Collection的子接口,set接口没有提供额外的方法。
  • Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。
  • Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法。因此存放到Set集合中的元素一定要注意equals方法的重写。

Set的常用实现类有:HashSet、TreeSet、LinkedHashSet。

11.5.1 HashSet

1、概述

  • HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。
  • HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取和查找性能。
  • HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。
    • 当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值,通过某种散列函数决定该对象在 HashSet 中的存储位置。(这个散列函数会与底层数组的长度相计算得到在数组中的下标,并且这种散列函数计算还尽可能保证能均匀存储元素,越是散列分布,该散列函数设计的越好)
    • 如果两个元素的hashCode()值相等,会再继续调用equals方法,如果equals方法结果为true,添加失败,如果为false,那么会保存该元素,但是该数组的位置已经有元素了,那么会通过链表的方式继续链接。
  • HashSet 具有以下特点:
    • 不能保证元素的排列顺序
    • HashSet 不是线程安全的
    • 集合元素可以有一个是 null
    •  
    • 底层也是数组,初始容量为16,当如果使用率超过0.75,(16*0.75=12)就会扩大容量为原来的2倍。(16扩容为32,依次为64,128….等)

       

      结论:存放到Set集合中的元素一定要注意equals和hashcode方法的重写。

      2、hashCode和equals方法

      重写equals()方法的原则:

      • 对称性:如果equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
      • 自反性:equals(x)必须返回是“true”。
      • 类推性:如果equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。
      • 一致性:如果equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。
      • 任何情况下,equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。

      重写 hashCode() 方法的基本原则

      • 在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值
      • 当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode() 方法的返回值也应相等
      • 对象中用作 equals() 方法比较的属性Field,都应该用来计算 hashCode 值

 

 


上一篇:
下一篇: