Java HashMap

标签(空格分隔): Java source-code hash-map


总结

  1. HashTable的基本数据结构
  2. Entry的hash与table的长度计算indexFor才能算出entry在table中的链表头节电位置
  3. HashMap中比较key是否相同的算法 e.hash == hash && ((k = e.key) == key || key.equals(k))
  4. == 与 equal
  5. hashMap的遍历方式,hashMap本身没有实现Iteratort,提供了三个set,entrySet keySet vaulues,三者都是基于HashIterator,都是获取entry进行数据访问的。

HashMap 的数据结构模型

table: Entry[],Entry的数组,table[i]里存着hash(key)对应着某个hash值的链表的头指针。

Entry:范型数据结构,就是一个链表的节点,key,value,next(指向下一个节点),hash

放入Put

加入一个key-value键值对,即要加入一个entry。首先计算entry的hash,计算该hash应该存在table中的那个链表中(index(hash,table.length)) ,从头节点开始寻找

  1. 若已经有存在的 key,则替换将该entry的value更新,返回oldvalue
  2. 若为新的key,构建新的entry,加入此hash对应的链表中

查看key的比较

Java 示例:

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为自定义的类时,要注意==与equals方法。

equals 与 ==
1.基本数据类型,也称原始数据类型。
byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号(==),比较的是他们的值。
2.复合数据类型(类)
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。
JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。

HashMap中存入的是新的值是,会

addEntry(hash, key, value, i);
return null; void addEntry(int hash, K key, V value, int bucketIndex) {
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
} createEntry(hash, key, value, bucketIndex);
}

resize之后,要进行旧表到新表的transfer,注意两点,

1 旧的一条链表保存的是按照原来hash值计算出来的index(hash, table.length)一致,换成新表后,链表结构要改变,并不是单纯的把链表挪位置。想想,要是单纯的把链表在table上进行挪位子,resize也就没有意义了,resize就是为了减少hash冲突的。

2 transfer函数可以认真看下

transfer函数

void transfer(Entry[] newTable, boolean rehash) {
int newCapacity = newTable.length;
for (Entry<K,V> e : table) {
while(null != e) {
Entry<K,V> next = e.next;
if (rehash) {
e.hash = null == e.key ? 0 : hash(e.key);
}
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
}
}
}

HashSet

HashSet实现基于HashMap,key比较出来相等时候,会进行覆盖,因而保持了Set中相同的元素只出现一次。

private transient HashMap<E,Object> map;

【Java】 HashMap的更多相关文章

  1. 【Java】HashMap源码分析——常用方法详解

    上一篇介绍了HashMap的基本概念,这一篇着重介绍HasHMap中的一些常用方法:put()get()**resize()** 首先介绍resize()这个方法,在我看来这是HashMap中一个非常 ...

  2. 【Java】HashMap源码分析——基本概念

    在JDK1.8后,对HashMap源码进行了更改,引入了红黑树.在这之前,HashMap实际上就是就是数组+链表的结构,由于HashMap是一张哈希表,其会产生哈希冲突,为了解决哈希冲突,HashMa ...

  3. 【java】HashMap、Map、Set、HashMap.put()、HashMap.keySet()、HashMap.entrySet()、Map.Entry内部类

    package com.tn.hashMap; public class Student { private String id; private String name; public Studen ...

  4. 【JAVA】HashMap的原理及多线程下死循环的原因

    再次翻到以前工作中遇到的一个问题,HashMap在多线程下会出现死循环的问题,以前只是知道会死循环,导致CPU100%把机器拖跨,今天来彻底看看 首先来看下,HashMap的原理:HashMap是一个 ...

  5. 【Java】HashMap实现原理---数据结构

    作为一个程序猿,特别是Java后端的,应该全部人都用过HashMap,也都知道HaspMap是一个用于存储Key-Value键值对的集合.与此同时我们把每一个键值对也叫做 Entry. 而这些Entr ...

  6. 【JAVA】HashMap源码阅读

    目录 1.关键的几个static参数 2.内部类定义Node节点 3.成员变量 4.静态方法 5.HashMap的四个构造方法 6.put方法 7.扩容resize方法 8.get方法 9.remov ...

  7. 【JAVA】ThreadLocal源码分析

    ThreadLocal内部是用一张哈希表来存储: static class ThreadLocalMap { static class Entry extends WeakReference<T ...

  8. 【Java】模拟Sping,实现其IOC和AOP核心(二)

    接着上一篇,在上一篇完成了有关IOC的注解实现,这一篇用XML的方式实现IOC,并且完成AOP. 简易的IOC框图 注解的方式实现了左边的分支,那么就剩下右边的XML分支: XmlContext:这个 ...

  9. 【Java】模拟Sping,实现其IOC和AOP核心(一)

    在这里我要实现的是Spring的IOC和AOP的核心,而且有关IOC的实现,注解+XML能混合使用! 参考资料: IOC:控制反转(Inversion of Control,缩写为IoC),是面向对象 ...

随机推荐

  1. Mac 下 visual studio code 编辑器 设置为中文

    1,mac系统VScode设置中文 macOS 快捷键:command + shift + p 输入搜索 configure language     1.Ctrl+Shift+P 打开命令 2.搜索 ...

  2. 【kernel】Centos 云上升级内核失败 如何处理【笔记记录转】

    Centos7选定默认启动的内核版本 vim /etc/grub2.cfg   修改timeout =5   修改成30天 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附 ...

  3. RT-Thread--内存管理

    内存管理的功能特点 RT-Thread 操作系统在内存管理上,根据上层应用及系统资源的不同,有针对性地提供了不同的内存分配管理算法.总体上可分为两类:内存堆管理与内存池管理,而内存堆管理又根据具体内存 ...

  4. Resource接口

    [转]https://blog.csdn.net/hbtj_1216/article/details/85487787 参考:官方文档 1 简介 Java标准库中的java.net.URL类和标准处理 ...

  5. python实现字符串中如果遇到连续重复的字符只出现一次非去重

    需求:在一个字符串中, 如果遇到连续重复的字符只出现一个,(不是去重) 例:str1 = 'aabbccddaabbccdd' 输出结果为:‘abcdabcd’ 具体实现代码如下: def func( ...

  6. Python中日志logging模块

    # coding:utf-8 import logging import os import time class Logger(object): def __init__(self): # 创建一个 ...

  7. 动态 DP 总结

    目录 例题1:模拟赛题 代码: 例题2 例题3:带修改树上最大独立集. 代码: 注:部分参考 https://www.luogu.org/blog/gkxx-is-here/what-the-hell ...

  8. 判断大文件是否上传成功(一个大文件上传到ftp,判断是否上传完成)

    大文件上传ftp,不知道有没有上传完成,如果没有上传完成另一个程序去下载这个文件,导致下载不完整. 判断一个文件是否上传完成的方法: /** * 间隔一段时间去计算文件的长度来判断文件是否写入完成 * ...

  9. mysql查询重复数据

    SELECT * FROM oa_user ) ORDER BY UserName oa_user表名,UserName需要查重复的字段名

  10. 38 | 都说InnoDB好,那还要不要使用Memory引擎?

    我在上一篇文章末尾留给你的问题是:两个 group by 语句都用了 order by null,为什么使用内存临时表得到的语句结果里,0 这个值在最后一行:而使用磁盘临时表得到的结果里,0 这个值在 ...