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。 所以修改不修改无所谓。
今天就理解到这里…… 如有错误,请各路大侠多多指正
分享到:
相关推荐
此篇文章是学习Java中的集合时自己总结的笔记,主要记录了集合的底层原理、List、Set、Queue等集合的特点、集合的实现类的特点以及各个实现类底层是原理。
Set:元素不可以重复,是无序。p508 Set接口中的方法和Collection一致。 |--HashSet: 内部数据结构是哈希表 ,是不同步的。 如何保证该集合的元素唯一性呢? 是通过对象的hashCode和equals方法来完成对象唯一性的...
// set容器中的对象不允许重复 // set容器接口的实现类有HashSet和 LinkedHashSet两个 // HashSet不保证迭代顺序, LinkedHashSet按照元素插入的顺序迭代. // 学习List对象容器的使用 // List容器中的对象允许重复 ...
主要为大家详细介绍了java中set接口使用方法,介绍了Java中Set集合接口实现插入对象不重复的原理,感兴趣的小伙伴们可以参考一下
Java集合框架中的Set接口是一种不允许包含重复元素的集合。Set接口继承自Collection接口,因此它具有Collection接口定义的所有方法。同时,Set接口还具有自己的特殊方法,例如:添加元素、删除元素、判断元素是否...
· Set 接口继承 Collection,但不允许重复,使用自己内部的一个排列机制。 · List 接口继承 Collection,允许重复,以元素安插的次序来放置元素,不会重新排列。 · Map接口是一组成对的键-值对象,即所持有...
而Set是一个不重复的集合,元素是无序的。 Collection接口的常用方法 1、add(Object obj):向集合中添加一个元素obj; 2、addAll(Collection c):将集合c中的所有元素添加到该集合中; 3、remove(Object obj):从...
3、类型安全:Java集合框架是类型安全的,即只能存储指定类型的对象,不允许存储不同类型的对象。 4、线程安全:Java集合框架中的某些数据结构和算法是线程安全的,可以在多线程环境中使用。 Java集合框架中的接口 ...
集合类Collection:集合层次中的根接口,JDK没有提供这个接口直接的实现类。 Set:不能包含重复的元素。SortedSet是一个按照升序排列元素的Set。 List:是一个有序的集合,可以包含重复的元素。提供了按索引访问的...
计算机后端-Java-Java核心基础-第24章 集合01 21. Set的无序性与不可重复性的理解.avi
本章目标 掌握Java集合框架中的三大类集合的...key不重复 Collection Framework Collection Framework java.util.ArrayList(掌握) ArrayList的特征: 动态数组,用户可以根据元素的索引访问元素,索引从0开始。 允许
不可重复: 在一个Set集合中不能出现相同元素 interface Set --| class HashSet 底层是哈希表存储数据 --| class TreeSet 底层存储数据是一个二叉树 1.2 HashSet 1.2.1 底层结构 package com.qfedu.b_set; import ...
Set集合类似于一个容器,程序把很多对象保存到Set集合中,Set集合对添加顺序不记录,当有重复的对象保存到Set集合时,不会新增后加的重复对象。 Set集合的特点 Set集合无重复元素,add()方法添加相同元素时,...
65、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别 17 66、HashMap和Hashtable的区别 17 67、说出ArrayList,Vector, LinkedList的存储性能和特性 17 68、java中有几...
Set (注重独⼀⽆⼆的性质): 存储的元素是⽆序的、不可重复的。 Map (⽤ Key 来搜索的专家): 使⽤键值对(kye-value)存储,类似于数学上的函数 y=f(x), “x”代表 key,"y"代表 value,Key 是⽆序的、不可重复的,...
Map集合中的key和set集合存储元素特点相同。 Map接口的实现类: HashMap:线程不安全,底层是哈希表数据结构 Hashtable(用的很少):线程安全,底层也是哈希表结构,所有方法都带有synchronized关键字。 ...
HashSet 是 Java 中的一个集合类,它实现了 Set 接口并提供了基于哈希表的无序、不重复元素的集合。具体来说,它是通过哈希表(实际上是一个 HashMap 实例)来存储元素的。 以下是 HashSet 的一些主要特点: 无序...
Java集合类是Java.util包中的重要内容,它提供了一套性能优良、使用方便的接口和类,用于处理对象的集合。这些类主要用于存储、...Set接口是无序的集合,元素不能重复。Set接口的实现类包括HashSet、LinkedHashSet等。
Java学生管理系统(控制台)实现了学生姓名,学号,居住地,年龄的添加,...解决了学号的重复问题,不存在的问题等。为个人原创作品。内有详细注释,可供使用。 文件编码格式为gbk,如有乱码,请调整编译器的编码格式。
ps:要想往集合中存放基本数据类型,必须转换为对应的包装类 Collection -- 集合接口 List -- List接口(添加了许多针对下标操作的方法) 特点:有序的,且可重复 ArrayList: 数据结构:一维数组 ...