Collection的子接口之Set接口

Set包含

  1. HashSet:作为Set接口的实现类;线程不安全;可以存储null值
  2. LinkedHashSet:作为HashSet的子类;遍历内部数据时,可以按照添加的顺序遍历
  3. TreeSet:可以按照添加对象的指定属性,进行排序

Set接口的特点

  1. 无序性:不等于随机性。存储的数据在底称数组中并非按照数组的索引顺序添加,而是根据数据的哈希值决定的。
  2. 不可重复性:保证添加的元素按照equals()判断时,不能返回true。即:相同的元素只能添加一个。

HashSet添加元素过程

  1. 当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法
    来得到该对象的 hashCode 值,然后根据 hashCode 值,通过某种散列函数决定该对象
    在 HashSet 底层数组中的存储位置。
  2. 如果两个元素的hashCode()值不相等,则直接添加值
  3. 如果两个元素的hashCode()值相等,会再继续调用equals方法,如果equals方法结果
    为true,添加失败;如果为false,那么会保存该元素,但是该数组的位置已经有元素了,
    那么会通过链表的方式继续链接。
  4. 如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相
    等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。

注意:

在Java7中:当两个数a,b的hashCode()值相同时,但内容不同时,新元素放到数组中,指向原来放在数组中的元素,并且原来的元素不在原来的位置。即新元素不断往数组中放,旧元素跳出数组。

在Java8中:当两个数a,b的hashCode()值相同时,但内容不同时,新元素放在下面,由在数组中原来的元素指向新元素。

总结:七上八下

要求:

  1. 向Set中添加的数据,其所在的类一定要重写hashcode()和equals()
  2. 重写的hashcode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码

LinkedHashSet的使用

  1. LinkedHashSet 是 HashSet 的子类
  2. LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,
    但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入
    顺序保存的。
  3. LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全
    部元素时有很好的性能,更适合遍历操作。

TreeSet的使用

  1. 向TreeSet中添加的数据,要求的时相同的类
  2. 两种排序方式:自然排序(实现Comparable接口)和定制排序(Comparator)
  3. 自然排序中,比较2个对象是否相同的标准:compareTo返回0,不再是equals
  4. 定制排序中,比较2个对象是否相同的标准:compare返回0,不再是equals
posted on 2021-07-03 22:28  yicurtain  阅读(67)  评论(0)    收藏  举报