`
ymm8505
  • 浏览: 32292 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java中的Set集合 怎么保障不重复?

    博客分类:
  • Java
阅读更多
Java中的Set集合 怎么保障不重复?

大家可能都知道Set是一个无序的不可以重复的集合。凡事想一个为什么?
打开源码看一眼:
Set是一个接口,常用的Set实现类那就是HashSet了。
-------------------------------------------------
public HashSet() {
map = new HashMap<E,Object>();
    }
-------------------------------------------------

这是HashSet的构造方法。 可以看到HashSet内部其实就是一个HashMap
【添加元素的方法】
/** 
     * 如果此set中尚未包含指定元素,则添加指定元素。 
     * 更确切地讲,如果此 set 没有包含满足(e==null ? e2==null : e.equals(e2)) 
     * 的元素e2,则向此set 添加指定的元素e。 
     * 如果此set已包含该元素,则该调用不更改set并返回false。 
     * 
     * 底层实际将将该元素作为key放入HashMap。 
     * 由于HashMap的put()方法添加key-value对时,当新放入HashMap的Entry中key 
     * 与集合中原有Entry的key相同(hashCode()返回值相等,通过equals比较也返回true), 
     * 新添加的Entry的value会将覆盖原来Entry的value,但key不会有任何改变, 
     * 因此如果向HashSet中添加一个已经存在的元素时,新添加的集合元素将不会被放入HashMap中, 
     * 原来的元素也不会有任何改变,这也就满足了Set中元素不重复的特性。 
     * @param e 将添加到此set中的元素。 
     * @return 如果此set尚未包含指定元素,则返回true。 
     */
public boolean add(E e) {
return map.put(e, PRESENT)==null;
    }
看一下map的定义:
HashSet 中定义了这样的两个变量:
    private transient HashMap<E,Object> map;
    private static final Object PRESENT = new Object();
我们再看一下上面的 add() 方法。
map.put(o, PRESENT)==null
实际执行的是 map 的方法,并且我们添加的对象是 map 中的 key,value 是执行的同一个对象 PRESENT.
因为map中的key是不允许重复的,所以set中的元素不能重复。
==============================================================================
根本问题还是没有解决那继续问?为什么HashMap中的Key不允许重复?
HashMap的往里放元素的源码!!!

public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        //遍历链表
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            //如果key在链表中已存在,则替换为新value  HashMap 可以重复put同一个Key值不同的对象。
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

分步骤判断添加的Key值:
1、取到新添加Key值得hashCode值。
2、确定数组的index 根据Key的hashCode值和当前table的长度按位取并  h & (length-1);
    按位取并,作用上相当于取模mod或者取余%。
    这意味着数组下标相同,并不表示hashCode相同
3、这里的hashcode在equals前面,JVM会先判断或运算||的前部分,当这一前部分为true的时候判断终止,返回true(这是为了提高JVM的效率),所以当hashcode不同的时候,equals是不会执行的。


总结为什么Set里面不能有重复?
因为HashMap在put一个Key时会判断,将要放进去的Key的hash值与 目前HashMap中定位到的那个Key的hash值比较。
如果hash值相当,继续比较 这两个对象的地址或者内容是否相当。
如果相当:判断出来要添加的Key与HashMap中的Key重复,把Value的值给替换成最新的。
HashSet中的Value是一个固定值PRESENT。 所以修改不修改无所谓。


今天就理解到这里…… 如有错误,请各路大侠多多指正
1
1
分享到:
评论

相关推荐

    一眼看懂Java中的集合

    此篇文章是学习Java中的集合时自己总结的笔记,主要记录了集合的底层原理、List、Set、Queue等集合的特点、集合的实现类的特点以及各个实现类底层是原理。

    java集合知识-map、set等

    Set:元素不可以重复,是无序。p508 Set接口中的方法和Collection一致。 |--HashSet: 内部数据结构是哈希表 ,是不同步的。 如何保证该集合的元素唯一性呢? 是通过对象的hashCode和equals方法来完成对象唯一性的...

    java中set、list和map的使用方法实例

    // set容器中的对象不允许重复 // set容器接口的实现类有HashSet和 LinkedHashSet两个 // HashSet不保证迭代顺序, LinkedHashSet按照元素插入的顺序迭代. // 学习List对象容器的使用 // List容器中的对象允许重复 ...

    java中set接口使用方法详解

    主要为大家详细介绍了java中set接口使用方法,介绍了Java中Set集合接口实现插入对象不重复的原理,感兴趣的小伙伴们可以参考一下

    Java集合框架Set接口.pdf

    Java集合框架中的Set接口是一种不允许包含重复元素的集合。Set接口继承自Collection接口,因此它具有Collection接口定义的所有方法。同时,Set接口还具有自己的特殊方法,例如:添加元素、删除元素、判断元素是否...

    JAVA集合(List,Set,Map)

     · Set 接口继承 Collection,但不允许重复,使用自己内部的一个排列机制。 · List 接口继承 Collection,允许重复,以元素安插的次序来放置元素,不会重新排列。 · Map接口是一组成对的键-值对象,即所持有...

    Java集合框架Collection接口.pdf

    而Set是一个不重复的集合,元素是无序的。 Collection接口的常用方法 1、add(Object obj):向集合中添加一个元素obj; 2、addAll(Collection c):将集合c中的所有元素添加到该集合中; 3、remove(Object obj):从...

    Java集合框架.pdf

    3、类型安全:Java集合框架是类型安全的,即只能存储指定类型的对象,不允许存储不同类型的对象。 4、线程安全:Java集合框架中的某些数据结构和算法是线程安全的,可以在多线程环境中使用。 Java集合框架中的接口 ...

    java的集合类教学

    集合类Collection:集合层次中的根接口,JDK没有提供这个接口直接的实现类。 Set:不能包含重复的元素。SortedSet是一个按照升序排列元素的Set。 List:是一个有序的集合,可以包含重复的元素。提供了按索引访问的...

    计算机后端-Java-Java核心基础-第24章 集合01 21. Set的无序性与不可重复性的理解.avi

    计算机后端-Java-Java核心基础-第24章 集合01 21. Set的无序性与不可重复性的理解.avi

    Java高级程序设计:第7章-集合框架.pptx

    本章目标 掌握Java集合框架中的三大类集合的...key不重复 Collection Framework Collection Framework java.util.ArrayList(掌握) ArrayList的特征: 动态数组,用户可以根据元素的索引访问元素,索引从0开始。 允许

    关于Set集合

    不可重复: 在一个Set集合中不能出现相同元素 interface Set --| class HashSet 底层是哈希表存储数据 --| class TreeSet 底层存储数据是一个二叉树 1.2 HashSet 1.2.1 底层结构 package com.qfedu.b_set; import ...

    Java—Set集合详解(HashSet/LinkedHashSet/TreeSet/EnumSet)

      Set集合类似于一个容器,程序把很多对象保存到Set集合中,Set集合对添加顺序不记录,当有重复的对象保存到Set集合时,不会新增后加的重复对象。 Set集合的特点 Set集合无重复元素,add()方法添加相同元素时,...

    java面试宝典

    65、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别 17 66、HashMap和Hashtable的区别 17 67、说出ArrayList,Vector, LinkedList的存储性能和特性 17 68、java中有几...

    Java集合框架常见面试题.pdf

    Set (注重独⼀⽆⼆的性质): 存储的元素是⽆序的、不可重复的。 Map (⽤ Key 来搜索的专家): 使⽤键值对(kye-value)存储,类似于数学上的函数 y=f(x), “x”代表 key,"y"代表 value,Key 是⽆序的、不可重复的,...

    Java中的小知识 —- Map集合

    Map集合中的key和set集合存储元素特点相同。 Map接口的实现类: HashMap:线程不安全,底层是哈希表数据结构 Hashtable(用的很少):线程安全,底层也是哈希表结构,所有方法都带有synchronized关键字。 ...

    java集合-HashSet的使用

    HashSet 是 Java 中的一个集合类,它实现了 Set 接口并提供了基于哈希表的无序、不重复元素的集合。具体来说,它是通过哈希表(实际上是一个 HashMap 实例)来存储元素的。 以下是 HashSet 的一些主要特点: 无序...

    40道java集合面试题含答案(很全很详细)

    Java集合类是Java.util包中的重要内容,它提供了一套性能优良、使用方便的接口和类,用于处理对象的集合。这些类主要用于存储、...Set接口是无序的集合,元素不能重复。Set接口的实现类包括HashSet、LinkedHashSet等。

    Java学生管理系统(控制台)实现了学生姓名,学号,居住地,年龄的添加,删除,修改,查询。解决了学号的重复问题,不存在的问题等

    Java学生管理系统(控制台)实现了学生姓名,学号,居住地,年龄的添加,...解决了学号的重复问题,不存在的问题等。为个人原创作品。内有详细注释,可供使用。 文件编码格式为gbk,如有乱码,请调整编译器的编码格式。

    Java集合总结.txt

    ps:要想往集合中存放基本数据类型,必须转换为对应的包装类 Collection -- 集合接口 List -- List接口(添加了许多针对下标操作的方法) 特点:有序的,且可重复 ArrayList: 数据结构:一维数组 ...

Global site tag (gtag.js) - Google Analytics