hashmap

Java HashMap的原理、扩容机制、以及性能思考

江枫思渺然 提交于 2020-02-05 01:56:32
Java HashMap 说明 此文档所介绍的HashMap是基于JDK1.8之后的。此文受到网上很多其他Java生态爱好者文章的影响,写此文的目的是 系统的由浅入深 介绍下HashMap。在此感谢优秀文章作者的启发,由于自身实力有限,若有纰漏之处还请评论指导。 原理(参考[1][3]) HashMap类似于HashTable,本质都是存储的键值对,也就是 key 、 value , key 用作存储 初始索引 ,通过对其进行一系列运算把 value 映射存储到底层数据结构中。其存储的数据结构(JDK 1.8之后)如下: 数据结构 如上图所示,每个数组是有存储的是一个链表或者红黑树(视情况而定) * 数组 * 链表 * 红黑树 存储过程 graph LR;   key-->|进行Hash运算|key的hash值;   key的hash值-->|和hashMap的长度length-1进行&运算|数组下标index;   数组下标index-->|根据index存储该Entry也就是key, value|该index的数组; * 对key进行hash运算,得到key的hash值。 * 把key的hash值和hashMap的长度length进行&运算,得到index,index即为数据的索引地址,例如0,1,2,3。 * 把value存到 扩容(参考[2]) 性能(参考[4])

HashMap底层原理及简单实现

♀尐吖头ヾ 提交于 2020-02-04 23:46:50
HashMap可以用键值对来存储对象,所谓键值对,就是可以通过对象来寻找对象,是对数组索引的推广。 底层原理 存储结构 HashMap底层的实现采用了哈希表,基本结构是“数组+链表”。HashMap里面有一个叫table的Entry数组,Entry是一个用作链表节点的类,也就是说,数组的每个元素都对应着一个链表,结构如图所示: 存储过程 当调用HashMap的put方法时 首先,会计算key对象的哈希码,也就是调用它的hashcode()方法,一般是根据地址求出的。 然后,通过特定的算法计算出哈希码对应在 [0,数组长度-1) 区间内的哈希值,例如图中是让哈希码模16,求出对应的哈希值是15; 最后在table数组对应位置的链表中添加value对象(在添加的过程中会比较,将相同key值的对象覆盖掉) 注:两种最极端的计算哈希值算法:1.hashCode / hashCode 退化成一个链表 2.hashCode / 1退化成一个数组 注:为了提高效率,会将模运算换成位运算,当length是2的幂次时,hashCode & (length - 1)等效于hashCode % length 注:JDK8中,当链表长度大于8时,会将链表转化成一颗红黑树,提高查找效率 查找键值对过程 查找的过程类似于存储过程,只不过把存改为找到后返回。 根据key值求出hashCode

How to fill TableView with ObservableMap<KeyObject, ObservableList<CustomObject>> in JavaFX

守給你的承諾、 提交于 2020-02-04 22:22:47
问题 My Java programm produces a lot of data, with wich I construct individual ResultObject. Because only certain ResultsObjects will be of interest, I populate an ObservableHashMap<> with my results. The CustomObject consists of a handful ints + doubles and one JSONObject. With this CustomObject I want to map similar ResultObjects(which have certain properties in common) to that one CustomObject. While mapping and handling those results works as intended, I am pretty much helpless to populate a

How to fill TableView with ObservableMap<KeyObject, ObservableList<CustomObject>> in JavaFX

倾然丶 夕夏残阳落幕 提交于 2020-02-04 22:20:26
问题 My Java programm produces a lot of data, with wich I construct individual ResultObject. Because only certain ResultsObjects will be of interest, I populate an ObservableHashMap<> with my results. The CustomObject consists of a handful ints + doubles and one JSONObject. With this CustomObject I want to map similar ResultObjects(which have certain properties in common) to that one CustomObject. While mapping and handling those results works as intended, I am pretty much helpless to populate a

leetcode(六)

跟風遠走 提交于 2020-02-04 20:22:21
字符串中的第一个唯一字符 //利用哈希表来进行操作 class Solution { public int firstUniqChar ( String s ) { HashMap < Character , Integer > count = new HashMap < Character , Integer > ( ) ; int n = s . length ( ) ; // build hash map : character and how often it appears for ( int i = 0 ; i < n ; i ++ ) { char c = s . charAt ( i ) ; //返回指定索引处的字符 count . put ( c , count . getOrDefault ( c , 0 ) + 1 ) ; } // find the index for ( int i = 0 ; i < n ; i ++ ) { if ( count . get ( s . charAt ( i ) ) == 1 ) return i ; } return - 1 ; } } 哈希表还得继续学 算法的思路就是遍历一遍字符串,然后把字符串中每个字符出现的次数保存在一个散列表中。这个过程的时间复杂度为 O(N),其中 N 为字符串的长度。

3.java中的数据结构

喜夏-厌秋 提交于 2020-02-04 18:09:12
java中关于数据结构的工具类,暂时就这么称呼吧,其实也贼拉多,害看图包 上面的图肯定时不全,知识一些常用的。简单看一下上面列举出来的“工具类”的源码和一些常见的面试问题: List接口中的“工具类”,是一个有序集合,可以重复。 ArrayList: 底层使用数组实现的,数据是有序数据(插入的顺序),具有索引查找比较快,线程不安全。 属性: //默认容量 private static final int DEFAULT_CAPACITY = 10; //空集合 private static final Object[] EMPTY_ELEMENTDATA = {}; //默认空集合 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //数据存储数组,不参与序列化 transient Object[] elementData; //容量 private int size; //最大容量 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 构造方法: /* *指定长度的构造方法 */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) {

HashSet底层实现

女生的网名这么多〃 提交于 2020-02-04 12:05:02
\quad HashSet是采用哈希算法实现,底层实际是用HashMap实现的(HashSet本质就是一个简化版的HashMap),因此,查询效率和增删效率都比较高。我们来看一下HashSet的源码: public class HashSet < E > extends AbstractSet < E > implements Set < E > , Cloneable , java . io . Serializable { private transient HashMap < E , Object > map ; private static final Object PRESENT = new Object ( ) ; public HashSet ( ) { map = new HashMap < > ( ) ; } public boolean add ( E e ) { return map . put ( e , PRESENT ) == null ; } //以下代码省略 } \quad 我们发现里面有个map属性,这就是HashSet的核心秘密。我们再看add()方法,发现增加一个元素说白了就是在map中增加一个键值对,键对象就是这个元素,值对象是名为PRESENT的Object对象。说白了,就是“往set中加入元素

Hashtable和HashMap的区别

混江龙づ霸主 提交于 2020-02-04 08:20:03
Hashtable和HashMap的区别: 1.Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类; 2.Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;而对于HashMap,则需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解决: Map Collections.synchronizedMap(Map m) 这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。 3.在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。 Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现 HashMap允许将null作为一个entry的key或者value

JAVA中HashMap和Hashtable区别

爱⌒轻易说出口 提交于 2020-02-04 08:16:26
Hashtable和HashMap在Java面试中相当容易被问到,甚至成为了集合框架面试题中最常被考的问题,所以在参加任何Java面试之前,都不要忘了准备这一题。 我们先看2个类的定义 public class Hashtable extends Dictionary implements Map, Cloneable, <a href="http://lib.csdn.net/base/javase" class='replace_word' title="Java SE知识库" target='_blank' style='color:#df3434; font-weight:bold;'>Java</a>.io.Serializable public class HashMap extends AbstractMap implements Map, Cloneable, Serializable 可见Hashtable 继承自 Dictiionary 而 HashMap继承自AbstractMap Hashtable的put方法如下 public synchronized V put(K key, V value) { //###### 注意这里1 // Make sure the value is not null if (value == null) { //######

hashtable和hashmap

旧时模样 提交于 2020-02-04 07:59:00
1.hashtable和hashmap    [1]这两个结构都采用数组+链表实现,称作hashmap是因为它的每一个元素是一个key-value对。   [2]hashtable是线程安全的,它的每个方法中都加入了Synchronize方法,意思是多线程时可以直接调用提供的方法,而不用在外部进行加锁同步。    hashmap不是线程安全的,因此多线程时必须在外部加锁进行同步。   [3]hashtable不支持null key和null value。    hashmap支持null key和null value。null key只能有一个,null value可以作为正常的value。当get()方法返回null时,可能该key对应的value就是null,因此不能用get()来判断是否存在某个key,而应该用containsKey()啦判断。   [4]hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。    hashmap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。   [5]创建时,如果给定了容量初始值,那么Hashtable会直接使用你给定的大小,而HashMap会将其扩充为2的幂次方大小。也就是说Hashtable会尽量使用素数、奇数。而HashMap则总是使用2的幂作为哈希表的大小。之所以会有这样的不同