HashMap 和 HashSet
对于HashSet而言,系统采用Hash算法决定集合元素的存储位置,这样可以保证快速存取集合元素;
对于HashMap,系统将value当成key的附属,系统根据Hash算法来决定key的存储位置,这样可以保证快速存取集合key,而value总是紧随key存储。
(这些集合虽然号称存储的是java对象,但实际上并不会真正将java对象放入set集合中,而只是在Set集合中保留这些对象的引用。
当程序视图将多个key-value 放入HashMap中时,采用一种“Hash算法”来决定每个元素的存储位置。
1 public V put(K key, V value)
2 {
3 if(key == null)
4 return putForNullKey(value);
5 int hash = hash(key.hashCode());
6
7 int i = indexFor(hash, table.length);
8
9 for(Entry<K,V> e = table[i]; e!=null;e=e.next)
10 {
11 Object K;
12 if(e.hash==hash && ((k=e.key) == k || key.equals(k))
13 {
14 V oldValue = e.value;
15 e.value= value;
16 e.recordAccess(this);
17 return oldValue;
18 }
19 }
20 modCount ++;
21 addEnrty(hash,key,value,i);
22 return null;
23 }
一个重要的内部接口Map.Entry,每个Map.Entry其实就是一个Key-Value对。当系统决定存储HashMap中的key-value对是,只是根据key来计算并决定每个Entry的存储位置:如果两个Entry的key的hashCode()返回值相同,那么它们的存储位置相同;如果这两个key通过equals比较返回true,新添加的Entry的value将覆盖原有Entry的value,但key不会覆盖;如果这两个key通过equals比较返回false,新添加的Entry将与集合中原有Entry形成Entry链。见addEntry()方法:
1 void addEntry(int hash,K key,V value,int bucketIndex)
2 {
3 Entry<K,V> e = table[bucketIndex];
4 table[bucketIndex] = new Entry<K,V>(hash,key,value,e);
5 if(size++ >= threshold) //threshold包含HashMap能容纳的key-value对的极限。
6 resize(2*table.length);
7 }
table实质就是一个普通数组,每个数组都有一个固定一的长度,这个数组的长度就是HashMap的容量。
HashSet是基于HashMap实现的,HashSet底层采用HashMap来保存所有元素。
1 class Name
2 {
3 private String first;
4 private String last;
5 public Name(String first, String last)
6 {
7 this.first = first;
8 this.last = last;
9 }
10 public boolean equals(Object o)
11 {
12 if(this == o)
13 return true;
14 if(o.getClass() == Name.class)
15 {
16 Name n =(Name) o;
17 return n.first.equals(first) && n.last.equals(last);
18 }
19 return false;
20 }
21
22 public class HashSetTest
23 {
24 public static void main(String[] args)
25 {
26 Set<Name> s = new HashSet<Name>();
27 s.add(new Name("abc","123"));
28 System.out.println(s.contains(new Name("abc","123");
29 }
30 }
31
运行结果是false.
因为HashSet判断两个对象相等的标准除了要求通过equals方法比较返回true外,还要求两个对象的hashCode()返回值相等。
重写hashCode()方法:
public int hashCode()
{
return first.hashCode();
}
public boolean equals(Object o)
{
....
if(o.getClass() == Name.class)
{
Name n = (Name) o;
return n.first.equals(first);
}
...
}
HashMap 和 HashSet的更多相关文章
- HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别
①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...
- 谁可以说出HashMap和HashSet的相同点和不同点。
谁可以说出HashMap和HashSet的相同点和不同点. 2011-11-15 20:46ruoshui_t | 浏览 20310 次 Perl 2011-11-15 21:17 #知道行家专业创 ...
- [转] HashMap和HashSet的区别
HashMap和HashSet的区别是Java面试中最常被问到的问题.如果没有涉及到Collection框架以及多线程的面试,可以说是不完整.而Collection框架的问题不涉及到HashSet和H ...
- HashMap和HashSet的区别
理解HashSet及使用 HashMap和HashSet的区别是Java面试中最常被问到的问题.如果没有涉及到Collection框架以及多线程的面试,可以说是不完整.而Collection框架的问题 ...
- [置顶] HashMap HashTable HashSet区别剖析
HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面 1:HashSet底层采用的 ...
- HashMap、HashSet源代码分析其 Hash 存储机制
集合和引用 就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并不是真正的把 Java 对象放入数组中,只是把对象的引用放入数组中,每个数组元素都是一个引用变量. 实际上,HashSet ...
- HashMap HashTable HashSet
原文转载自 http://blog.csdn.net/wl_ldy/article/details/5941770 HashMap是新框架中用来代替HashTable的类 也就是说建议使用HashMa ...
- 【转】HashMap和HashSet的区别
原文网址:http://www.importnew.com/6931.html HashMap和HashSet的区别是Java面试中最常被问到的问题.如果没有涉及到Collection框架以及多线程的 ...
- HashMap HashTable HashSet区别剖析
HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面 1:HashSet底层采用的 ...
- java该HashTable,HashMap和HashSet
同一时候我们也对HashSet和HashMap的核心方法hashcode进行了具体解释,见<探索equals()和hashCode()方法>. 万事俱备,那么以下我们就对基于hash算法的 ...
随机推荐
- C# 判断未将对象引用设置到对象的实例,出错的代码到底在第几行
DataTable dt = null; try { var x = dt.Rows.Count; } catch(NullReferenceException nullexception) { Me ...
- OPA-Gatekeeper实验:对特定用户的更新时间窗口做限制
实验目的 OPA-Gatekeeper可以在Kubernetes 中,通过策略来实现一些额外的管理.安全方面的限制,例如:限制特定用户在 Namespace 中的行为权限 本次实验将在test命名空间 ...
- [luogu5344]逛森林
由于没有删边操作,可以先建出整棵森林,之后再用并查集判断是否连通,若连通必然与最后的森林相同 但如果用树链剖分+线段树的形式来优化建图,更具体如下: 建立两颗线段树,左边从儿子连向父亲,右边从父亲连向 ...
- 2020第十三届全国大学生信息安全竞赛创新实践能力赛rceme writerup
审计代码 传入参数a,进入parserIfLabel函数 发现参数a的模板,a的格式要匹配pattern,如{if:payload}{end if} 可知ifstr是a中匹配的第一组的值,即paylo ...
- tomcat指定特定版本的jdk
我是通过修改两个文件: setclasspath.bat和catalina.bat文件 linux在文件开头各自加上 export JAVA_HOME=/home/jdk/Java\jdk7\jdk1 ...
- k8s statefulset controller源码分析
statefulset controller分析 statefulset简介 statefulset是Kubernetes提供的管理有状态应用的对象,而deployment用于管理无状态应用. 有状态 ...
- selenium定位元素方法汇总
#打开网页前三步 from selenium import webdriver driver=webidriver.Chrome() driver.get("https://www.baid ...
- adb server version (32) doesn't match this client (39); killing...解决办法
输入今天遇到,安装AndroidSDK之后,已经配置好环境变量,输入adb可运行,但是输入adb devices之后就出现adb server version (32) doesn't match t ...
- Codeforces 1067E - Random Forest Rank(找性质+树形 dp)
Codeforces 题面传送门 & 洛谷题面传送门 一道不知道能不能算上自己 AC 的 D1E(?) 挺有意思的结论题,结论倒是自己猜出来了,可根本不会证( 开始搬运题解 ing: 碰到这样 ...
- Vue 中使用 TypeScript axios 使用方式
Vue 中使用 TypeScript axios 使用方式 方式一 import axios from 'axios'; Vue.prototype.$axios = axios; // 在 .vue ...