Set 接口概述:
Set 接口是Collection 的子接口,set 接口没有提供额外的方法;
Set 集合不允许包含相同的元素,如果试着把两个相同的元素加入通过一个 Set 集合中,则添加操作失败;
Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法;
一、存储无序,不可重复 (以HashSet为例说明)
无序性:不等于随机性。储存的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值存放;
不可重复性:保证添加的元素按照 equals() 判断时,不能返回 true。即:相同的元素只能添加一个;
二、添加元素的过程:(以HashSet为例)
我们向 HashSet 中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断数组此位置上是否已有元素:
如果此位置上没有其他元素,则元素 a 添加成功。-------->情况1;
如果此位置上有其他 b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
如果hash值不相同,则元素a添加成功; ---------->情况2;
如果hash值相同,则需要调用元素a 所在类的equals()方法;
equals()返回 true,元素a添加失败;
equals()返回false,元素a添加成功;------------>情况3;
对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上的数据以链表的方式存储。
JDK 7:元素a放到数组中,指向原来的元素;
JDK 8:原来的元素在数组中,指向元素a;
总结:七上八下;
Set 实现类之一:HashSet
HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合都是用这个实现类;
HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取、查找、删除性能;
HashSet具有以下特点:
不能保证元素的排列顺序;
HashSet 不是线程安全的;
集合元素可以是 null;
HashSet集合判断两个元素是否相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等;
对于存放在Set容器中的对象,对应的类一定要重写 equals() 和 hashCode(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。
LinkedHashSet:作为HashSet的子类,遍历其内部数据时,可以按照添加的顺序遍历,对于频繁的遍历操作,LinkedHashSet效率高于HashSet
原文:https://www.cnblogs.com/lililixuefei/p/13166741.html