set集合的特点是没有索引值,且元素不能重复。

 判断两个元素是否重复:两个元素的哈希值&&(地址值是否相同  ||  equals方法结果)

        即:先比较两个对象哈希值,如果哈希值不同,则两个元素不重复,如果哈希值相同,则继续比较地址值或equals方法,如果equals为true,则元素重复,如果为false则不重复。

以set集合中的hashset为例:


 

package Demo1;
import java.util.HashSet;
public class p10 {
     public static void main(String[] args) {
         
  HashSet<String> set = new HashSet<>();
              
              set.add("小明");
              set.add("小花");
              set.add("小强");
              set.add("小明");
              set.add("小花");
             System.out.println(set); 
     }
 }

打印结果为:[小强, 小明, 小花],


代码中一共添加了五个元素,而集合中只有小强, 小明, 小花。

出现这样的结果的原因是:

1.                        HashSet<String> set = new HashSet<>();

通过这一步,我们创建了一个hashset的对象:实质上是在“堆”中开辟了一个空间:

 首先我们知道hashset的底层结构是哈希表,在JDK1.8及以后,它由数组+链表/红黑树构成。

底层会创建一个默认长度为16的Object[],并将加载因子默认为0.75。

set java不允许有重复值 set集合不允许重复_set java不允许有重复值

2.                              set.add("小明");

新增流程为:

a.计算新增元素的哈希值(通过hashcode方法获取)

b.用哈希值%数组长度,得到的余数作为新增元素的索引值;

c.如果该索引值位置没有元素,可直接新增;

如果该索引值位置有元素,用equals方法去比较两个元素是否相同。

计算字符串"小明"的哈希值,就会在集合中找有没有"小明"哈希值的元素,首次新增,可直接新增。就会将元素"小明"存储到集合中去。

3.                          set.add("小花");
                             set.add("小强");

set集合在调用add方法时,会调用元素的hashcode和equals方法,判断元素是否重复。计算字符串的哈希值,就会在集合中找有没有哈希值的元素,就会将元素存储到集合中去。

4.                          set.add("小明");
                             set.add("小花");

add方法会调用hashCode方法,计算字符串"小明"和"小花"的哈希值,在集合中找有没有这个哈希值的元素,发现有(哈希冲突),会调用equals方法和哈希值相同的元素进行比较,equals方法返回true,认定两个元素相同,就不会存储"小明"和"小花"到集合中。

这就是set元素存储元素不重复的元素的原理。但是这有一个前提,存储元素必须重写hashcode和eqluas方法,保证元素不重复。