`
ymm8505
  • 浏览: 33398 次
  • 性别: 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 IntSet 数列集合

    如果该值已经存在,此操作通常不执行任何操作,因为集合不允许重复元素。 3. **移除数字**: 使用`remove(int value)`方法可以移除集合中的特定整数值。如果该值不存在于集合中,此操作也不会抛出异常。 4. **...

    java集合知识-map、set等

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

    java集合类详解(set list ArrayList等java集合类详述)

    Set 是一个不能包含重复元素的集合,SortedSet 是一个按照升序排列元素的 Set。List 是一个有序的集合,可以包含重复的元素,并提供了按索引访问的方式。Map 是一个包含了 key-value 对的集合,SortedMap 是一个按照...

    java泛型集合 java集合 集合 java Collection

    Java 泛型集合和Java集合框架是Java编程中不可或缺的部分,它们为开发者提供了高效的数据存储和操作机制。本文将深入探讨这两个主题,并着重讲解`Collection`接口及其在Java中的应用。 首先,Java泛型是一种在编译...

    java中关于集合的操作

    在Java编程语言中,集合框架是处理对象组的重要工具,它提供了一种高效、灵活的方式来存储和操作数据。本文将深入探讨Java中的集合操作,并结合PPT(虽然这里没有提供具体的PPT内容,但通常这样的资源会包含示例、...

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

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

    java 集合

    总的来说,Java集合框架是Java编程中不可或缺的一部分,理解和熟练掌握其原理与使用方法,对于提升代码质量、优化程序性能具有重要意义。在日常开发中,我们需要根据具体需求灵活运用各种集合类和接口,以实现高效的...

    Java中Set的深入研究

    Set接口是Java集合框架的一部分,它代表了一个数学抽象集合,即不允许包含重复元素的集合。更正式地讲,根据其Javadoc文档,Set是一个不包含任何重复元素的集合。具体来说,Set不允许包含满足`e1.equals(e2)`条件的...

    JAVA中的集合和js中集合

    虽然JavaScript原生并不像Java那样提供了一套完整的集合框架,但在ES6中引入了几个新的内置对象来处理集合操作: - **`Array`**:类似于Java中的`List`,但JavaScript的数组支持更多灵活的操作,比如动态调整长度。...

    Tedu一阶段JavaSet集合和List集合

    ### Tedu一阶段Java Set集合和List集合详解 #### 一、集合概述 - **集合的概念**:在Java中,集合是一种容器,用于存储多个对象。它可以存储不同类型的对象,并且提供了一系列的操作来管理这些对象。 - **...

    Java中的Set集合简单汇总解析

    Java中的Set集合简单汇总解析 Set接口简介: Set接口是Java集合框架中的一个重要接口,它继承自Collection接口,并没有对Collection接口进行功能上的扩充。Set接口的主要特点是元素无序,并且都会以某种规则保证...

    Java-Java集合体系-List-Set

    在Java中,集合主要分为三大接口:List、Set和Map。这些接口各有特点,适用于不同的应用场景。 一、List接口 List接口是单列集合的子接口,它允许存储重复的元素,并且元素具有顺序性。List接口提供了丰富的操作...

    java集合与通用集合

    `Set`接口确保集合中的元素唯一,不允许重复,并且支持数学集合操作,如交集和并集。常见的实现类有`HashSet`、`TreeSet`和`LinkedHashSet`。`List`接口则维护元素的顺序,并允许通过索引访问,常见的实现类有`...

    java集合思维导图

    Java集合框架是Java编程语言中的一个核心部分,它为数据存储和管理提供了高效且灵活的解决方案。本思维导图及总结旨在深入理解并掌握Java集合的相关概念和使用方法。 首先,我们来了解一下Java集合框架的基本构成。...

    java中三种集合set、map、list的区别与联系

    在Java编程语言中,集合框架提供了多种数据结构来存储和操作数据,其中最常用的是`Set`、`Map`和`List`。这三种集合类型各自具有独特的特性和用途,理解它们之间的区别与联系对于有效地使用Java进行数据管理至关重要...

    java基础之集合

    - **Set**:不允许重复元素的集合,不保证元素的顺序。 - **HashSet**:基于哈希表实现的集合,提供了高效的添加和查找操作,但不保证元素的顺序。 - **TreeSet**:基于红黑树实现的集合,可以自动排序元素,支持...

    浅析Java中的set集合类型及其接口的用法

    Java中的Set集合是一种...总之,Java中的Set集合类型提供了存储不重复元素的功能,其中HashSet强调性能,而TreeSet强调有序性。了解它们的工作原理以及如何正确使用它们,对于编写高效且功能完善的Java程序至关重要。

Global site tag (gtag.js) - Google Analytics