HashMap

  • 无序(每次resize的时候都会变)
  • 非线程安全
  • key和value都看可以为null
  • 使用数组和链表实现
  • 查找元素的时候速度快

几个重要属性:

  • loadFactor:用来计算threshold
  • threshold:决定map是否需要扩容,threshold = capacity * loadFactor

构造函数

// 构造函数中初始化了threadhold和loadFactor
public HashMap(int initialCapacity, float loadFactor) {if (initialCapacity < 0)throw new IllegalArgumentException("Illegal initial capacity: " +initialCapacity);if (initialCapacity > MAXIMUM_CAPACITY)initialCapacity = MAXIMUM_CAPACITY;if (loadFactor <= 0 || Float.isNaN(loadFactor))throw new IllegalArgumentException("Illegal load factor: " +loadFactor);this.loadFactor = loadFactor;threshold = initialCapacity;init();
}

put

public V put(K key, V value) {if (table == EMPTY_TABLE) {inflateTable(threshold);}if (key == null)// 添加key为null的元素,因为key不能重复,只能有一个key为null的元素return putForNullKey(value);int hash = hash(key);int i = indexFor(hash, table.length);// 先查找链表里面是否存在key相同的entry,如果有就直接替换for (Entry<K,V> e = table[i]; e != null; e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}// 如果没有key相同的entry,新加一个entrymodCount++;addEntry(hash, key, value, i);return null;
}// 取key的哈希值
final int hash(Object k) {int h = hashSeed;if (0 != h && k instanceof String) {return sun.misc.Hashing.stringHash32((String) k);}h ^= k.hashCode();// number of collisions (approximately 8 at default load factor).// 因为hashCode如果写的不好的话可能会使碰撞出现的次数较多,所以使用移位运算再次hash// 使用这中方法hash的原因:http://www.iteye.com/topic/709945h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4);
}void addEntry(int hash, K key, V value, int bucketIndex) {if ((size >= threshold) && (null != table[bucketIndex])) {// 如果size大于阈值threshold则扩容resize(2 * table.length);hash = (null != key) ? hash(key) : 0;bucketIndex = indexFor(hash, table.length);}// 将entry添加到链表中createEntry(hash, key, value, bucketIndex);
}void resize(int newCapacity) {Entry[] oldTable = table;int oldCapacity = oldTable.length;if (oldCapacity == MAXIMUM_CAPACITY) {threshold = Integer.MAX_VALUE;return;}Entry[] newTable = new Entry[newCapacity];// 每次扩容之后都要重新散列元素,因为table.length 变化了transfer(newTable, initHashSeedAsNeeded(newCapacity));table = newTable;threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
}// 新建一个entry,并放入链表的头部
void createEntry(int hash, K key, V value, int bucketIndex) {Entry<K,V> e = table[bucketIndex];table[bucketIndex] = new Entry<>(hash, key, value, e);size++;
}

Hashtable

  • key和value都不能为null
  • 线程安全(但是效率没有ConcurrentHashMap高,读写锁,分段锁)
  • key必须实现hashCode和equals方法
  • 无序

在实现上除了put、get等方法是synchronized和hash方法不同之外,基本和HashMap一样

转载于:https://www.cnblogs.com/sunshine-2015/p/6124276.html

Java 集合 — HashMap相关推荐

  1. Java集合HashMap

    HashMap Map接口的一个实现类 用于存储键值对映射关系 重复键 如果,出现重复键,将覆盖原有键的Value值 package bhz.aio;import java.util.HashMap; ...

  2. Java集合—HashMap底层原理

    原文链接:最通俗易懂搞定HashMap的底层原理 HashMap的底层原理面试必考题.为什么面试官如此青睐这道题?HashMap里面涉及了很多的知识点,可以比较全面考察面试者的基本功,想要拿到一个好o ...

  3. Java集合——HashMap、HashTable以及ConCurrentHashMap异同比较

    转发:https://www.cnblogs.com/zx-bob-123/archive/2017/12/26/8118074.html 0. 前言 HashMap和HashTable的区别一种比较 ...

  4. 深入java集合-HashMap

    本文为读书笔记,书籍为java并发编程的艺术 hashmap资料来自b站黑马 文章目录 1.HashMap 1.1 HashMap成员变量 问题: 为什么必须是2的n次幂?如果输入值不是2的幂比如10 ...

  5. 分析了解JDK1.8版本的Java集合HashMap的put()方法

    hashMap是java最常用的Key-Value形式的集合.了解其原理和底层代码是很有必要的,今天就记录下对HashMap的.put()方法的研究分析(元素添加方法): 先说下个人研究分析结果: H ...

  6. java集合 HashMap的三种遍历方式

    前言: HashMap的集合中的比重是无可厚非的,由自身的数组+链表/红黑树构成的(JDK 1.8),这样使得HashMap优点表现出来: 数组查询效率快: 链表的插入和删除效率也加快 但是HashM ...

  7. Java集合—HashMap为什么2倍扩容

    原文作者:很閒很快樂 原文地址:HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式 HashMap的初始容量都是2的n次幂的形式存在的,而扩容也是2倍的原来的容量进行扩容,也就是扩容后的 ...

  8. Java集合- HashMap 的底层数据结构实现原理

    一.HashMap 的数据结构 JDK1.8 之前 JDK1.8 之前 HashMap 底层是 数组和链表 结合在一起使用也就是 链表散列. HashMap 通过 key 的 hashCode 经过扰 ...

  9. Java集合源码学习(四)HashMap

    一.数组.链表和哈希表结构 数据结构中有数组和链表来实现对数据的存储,这两者有不同的应用场景, 数组的特点是:寻址容易,插入和删除困难:链表的特点是:寻址困难,插入和删除容易: 哈希表的实现结合了这两 ...

最新文章

  1. Mysql学习总结(11)——MySql存储过程与函数
  2. android view flipper,安卓控件——ViewFlipper
  3. SAP 对话屏幕长文本编辑框
  4. 北斗导航 | 基于CRDSS(Comprehensive RDSS, 全面RDSS)的北斗抗干扰技术研究:RDSS+RNSS(论文翻译)
  5. php 初始化漏洞,这样做是不是不会引起PHP全局变量未初始化漏洞
  6. java垃圾回收机制的理解
  7. java web部署文档_javaweb项目实施部署文档
  8. Microsoft Endpoint Protection for Windows Azure客户技术预览版可供免费下载
  9. 原理+代码实战:SUID提权渗透
  10. linux c蜂鸣器驱动程序,〖Linux〗OK6410a蜂鸣器的驱动程序编写全程实录
  11. 基于51单片机远近光灯切换电路设计方案
  12. CVE-2017-8570漏洞利用
  13. 马来西亚-沙巴-亚庇游记
  14. oracle付款汇兑损益怎么产生,月末汇兑损益怎么算调整分录如何做
  15. 详细分析软件测试的14种类型
  16. 1. Nacos的安装与启动
  17. Ardupilot 增加一个mavlink消息(翻译官网)
  18. 钉钉机器人 换行功能
  19. EVE-NG上传部署Cisco CSR1000V 16.12 QEMU官方镜像
  20. java开发工程师面试问题,java面试题大汇总小山博客

热门文章

  1. 【C#小知识】C#中一些易混淆概念总结(三)---------结构,GC,静态成员,静态类...
  2. Java IO 体系结构
  3. BGP local-preference MED属性实验
  4. 利用NetBIOS名称与其他计算机通信
  5. 体验Windows 7的Superbar
  6. RPA实施过程中可能会遇到的14个坑
  7. 关闭Windows 8的metro UI的方法汇总
  8. Caused by: org.xml.sax.SAXParseException: 不允许有匹配 [xX][mM][lL] 的处理指令目标。
  9. x-pack watch邮件报警配置
  10. 小程序这件事 撸起袖子加油干