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算法的 ...
随机推荐
- 原生css实现fullPage的整屏滚动贴合
目录 1,前言 2,效果展示 3,属性说明 3.1 scroll-snap-type 3.2,scroll-snap-align 4,实际使用 4.1,兼容性 1,前言 今天摸鱼的时候,发现一个很有意 ...
- VSCode 微信小程序 开发环境配置 详细教程
本博客已暂停更新,需要请转新博客http://www.whbwiki.com/231.html 配置 VsCode 微信小程序开发环境并非不用官方的 微信小程序开发者工具 ,而是两者配合适用,可以极大 ...
- Java测试开发--Spring Tools Suite (STS) 简介(一)
sts是一个定制版的Eclipse,专为Spring开发定制的,方便创建调试运行维护Spring应用. 官网下载之后,可以看到一个sts-bundle,里面有三个文件夹,一个法律信息,一个tc Ser ...
- mybatis之结果集的映射方式
查询的几种情况 // 1)查询单行数据返回单个对象 public Employee getEmployeeById(Integer id ); // 2) 查询多行数据返回对象的集合 public L ...
- FZU ICPC 2020 寒假训练 1
B - Sum Problem In this problem, your task is to calculate SUM(n) = 1 + 2 + 3 + ... + n. Input The i ...
- zookeeper问题在公司可以 回到家用家里网不行 目前还没有解决
Opening socket connection to server 192.168.1.193/192.168.1.193:2181. Will not attempt to authentica ...
- ubuntu 首次登陆设置root密码
用过ubuntu的人都知道,ubuntu默认root密码是随机的,即每次开机都有一个新的root密码.我们可以在终端输入命令sudo passwd,然后输入当前用户的密码 给root用户设置密码 ...
- 【华为昇腾】 序言:从昇腾AI软硬件平台聊起
2021年是很值得纪念的一年,从上半年开始跟随导师编写有关华为昇腾软件栈CANN的教材,一年的时间反复迭代 终于快要出版了. 这一系列博客可以视作我从编者的角度,重新梳理的全书思路.明年入职商汤之后要 ...
- [loj2506]tree
2018年论文题,以下是论文前3章主要内容,与原题解相关部分为第4章中的启发式合并,也可快速跳至原题解 1.复杂度分析 Treap 定理1:$n$个节点的Treap的期望深度为$o(\log n)$ ...
- 回顾Servlet开发
1.建立的文件 2.servlet package com.shao.servlet; import javax.servlet.ServletException; import javax.serv ...