hashmap

集合框架之HashMap(一)

半城伤御伤魂 提交于 2020-03-01 08:33:16
HashMap是非常重要的数据结构,并且大部分面试都会问到,优秀的java程序员应当要对HashMap进行深入的了解,今天我们就来剖析一下它。 目录 HashMap简介 成员变量 get和put的流程 hashMap相关的面试题 总结 一.简介 首先,HashMap是一个无序key,value集合,它的底层存储是由数组加链表和红黑树结构组成的的。在进行添加,删除和查找时,效率非常高,如果不考虑哈希碰撞,一次定位就能完成操作,时间复杂度为O(1)。 下面是一个默认长度的hashMap。 二.hashMap的成员变量 1.初始大小 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 这个是值是数组长度,也就是数组的初始最大行数,当然如果碰撞比较多,也有可能hashMap存了200个值,但是容量还是16。当然这不是理想状态。 2.最大值 static final int MAXIMUM_CAPACITY = 1 << 30; 这个没有什么好说的,hashMap最大容量。 3.增长因子 static final float DEFAULT_LOAD_FACTOR = 0.75f; 增长因子,就是如果数组被占用的大小超过当前大小的75%时,就进行扩容,按照当前容量二倍创建一个新的Entry

HashMap Hashtable 的区别

时间秒杀一切 提交于 2020-03-01 04:55:24
Hashtable 和 HashMap 作为 Map 的基本特性 两者都实现了Map接口,基本特性相同 - 对同一个Key,只会有一个对应的value值存在 - 如何算是同一个Key? 首先,两个key对象的hash值相同,其次,key对象的equals方法返回真 内部数据结构 Hashtable和HashMap的内部数据结构相似 其基本内部数据结构是一个Entry数组 ( transient Entry[] table) - 数组元素为实现Map.Entry<K,V>接口的类,Hashtable和HashMap各自实现了自己的Entry类。 - Entry包含一个Key-value对,以及一个next指针指向另一个Entry。多个Entry可以组成一个单向链表。 常用操作 数据插入操作: put(key,value) - 根据Key的hash值计算出该Entry所应存放的位置(数组下标) - 若该数组元素为空,直接放置Entry到此处 - 若多个不同的Key所计算得到的数组下标相同,新加入的Key-value对(Entry)会被加入到Entry单向链表中。Hashtable和HashMap都是将其插入链表首部. - 若已经有相同的Key存在于这个链表中,则,新的value值会取代老的value - 当Map中存放的Entry数量超过其限制( 数组长度 * 负荷因子)时

HashMap源码理解

折月煮酒 提交于 2020-02-29 22:02:15
private static int roundUpToPowerOf2(int number) { return number >= MAXIMUM_CAPACITY ? MAXIMUM_CAPACITY : (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1; } Integer.highestOneBit方法是获取不大于本身的2^n的值,那该方法具体含义是: 获取新的数组容量值,如果给定值大于等于最大的容量,则返回最大容量,否则:如果容量小于等于1,则返回1,否则返回大于等于给定值的最接近的 2^n的值 容量为什么要是2^n次方呢?且看如下代码: static int indexFor(int h, int length) { // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2"; return h & (length-1); } 给方法是查找h(ash)在数组的索引位置;那现在看length为什么要是2^n次方呢? 点此查看 保证&之后的数据不大于length length-1之后,最低的n位都是1,那与h的&运算之后的值即是h的最低n位 采用length-1而不是直接length是因为2

为什么HashMap的容量必须为2的N次方?什么原理?

て烟熏妆下的殇ゞ 提交于 2020-02-29 21:50:38
我们知道在HashMap的初始化默认容量是16。通过构造方法可以设定一个初始化容量的参数initialCapacity,但是HashMap的构造方法内是这样写的: while (capacity < initialCapacity) capacity <<= 1; 也就是说实际上容量还是一个2的N次方的数。 为什么非要这样?毫无疑问是因为效率! 但是还是来看看原码是怎样实现的: static int indexFor(int h, int length) { return h & (length-1); } 这是HashMap中的一个调用最频繁的方法,用于计算一个Key对应的Hash桶的索引,Hash桶放在一个数组中,这个方法返回的就是数组的索引,为了更加平均的分配容器内的元素,采用的是取模运算来分配。参数里的h就是key的hashCode,length就是容量capacity。 这里假如h为70(二进制: 0100 0110 ),length为64(二进制: 0100 0000 ),length-1也就是63(二进制: 0011 1111 )。 h & (length-1) =01000110 & 00111111=110(十进制正好为6 ==length % h) 可以看到,如果length为2的N次方,取模运算可以变成位与运算,效率显著提高!但是要浪费一些空间。 来源:

Hessian 反序列化及相关利用链

試著忘記壹切 提交于 2020-02-29 19:40:39
作者:Longofo@知道创宇404实验室 时间:2020年2月20日 原文链接: https://paper.seebug.org/1131/ 前不久有一个关于Apache Dubbo Http反序列化的漏洞,本来是一个正常功能(通过正常调用抓包即可验证确实是正常功能而不是非预期的Post),通过Post传输序列化数据进行远程调用,但是如果Post传递恶意的序列化数据就能进行恶意利用。Apache Dubbo还支持很多协议,例如Dubbo(Dubbo Hessian2)、Hessian(包括Hessian与Hessian2,这里的Hessian2与Dubbo Hessian2不是同一个)、Rmi、Http等。Apache Dubbo是远程调用框架,既然Http方式的远程调用传输了序列化的数据,那么其他协议也可能存在类似问题,例如Rmi、Hessian等。@pyn3rd师傅之前在 twiter 发了关于Apache Dubbo Hessian协议的反序列化利用,Apache Dubbo Hessian反序列化问题之前也被提到过, 这篇文章 里面讲到了Apache Dubbo Hessian存在反序列化被利用的问题,类似的还有Apache Dubbo Rmi反序列化问题。之前也没比较完整的去分析过一个反序列化组件处理流程,刚好趁这个机会看看Hessian序列化、反序列化过程,以及

集合(三):Set

时光总嘲笑我的痴心妄想 提交于 2020-02-29 13:39:56
一:java.util.Set(interface)  Set是一种 不包含重复的元素 的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。 public interface Set extends Collection { // Query Operations } 接下来将简单介绍 Set下的几个实现类,如:HashSet,TreeSet,LinkedHashSet。 二:java.util.HashSet(class) 对于 HashSet 而言,它是基于 HashMap 实现的 , HashSet 底层维护了一个HashMap ,其采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSet 的源代码,可以看到如下代码: public class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable { // 使用 HashMap 的 key 保存 HashSet 中所有元素 private transient HashMap map; // 定义一个虚拟的 Object 对象作为 HashMap 的 value private static final Object

集合类题目

我的梦境 提交于 2020-02-29 13:18:10
1.Java 集合类框架的基本接口有哪些? Java 集合类提供了一套设计良好的支持对一组对象进行操作的接口和类。 Java 集合类里面最基本的接口有: Collection :代表一组对象,每一个对象都是它的子元素。 Set :不包含重复元素的 Collection 。 List :有顺序的 collection ,并且可以包含重复元素。 Map :可以把键 (key) 映射到值 (value) 的对象,键不能重复。 2. 为什么集合类没有实现 Cloneable 和 Serializable 接口? 集合类接口指定了一组叫做元素的对象。集合类接口的每一种具体的实现类都可以选择以它 自己的方式对元素进行保存和排序。有的集合类允许重复的键,有些不允许。 3. 什么是迭代器 (Iterator) ? Iterator 接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代 器实例的 迭代方法。迭代器可以在迭代的过程中删除底层集合的元素。 克隆 (cloning) 或者是序列化 (serialization) 的语义和含义是跟具体的实现相关的。因此,应该由 集合类的具体实现来决定如何被克隆或者是序列化。 4.Iterator 和 ListIterator 的区别是什么? 他们的区别:Iterator 可用来遍历 Set 和 List 集合,但是

JDK7与JDK8中HashMap的实现

天大地大妈咪最大 提交于 2020-02-29 02:59:33
JDK7中的HashMap HashMap底层维护一个数组,数组中的每一项都是一个Entry transient Entry<K,V>[] table; 我们向 HashMap 中所放置的对象实际上是存储在该数组当中; 而Map中的key,value则以Entry的形式存放在数组中 static class Entry<K,V> implements Map.Entry<K,V> { final K key; V value; Entry<K,V> next; int hash; 而这个Entry应该放在数组的哪一个位置上(这个位置通常称为位桶或者hash桶,即hash值相同的Entry会放在同一位置,用链表相连),是通过key的hashCode来计算的。 final int hash(Object k) { int h = 0; h ^= k.hashCode(); h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } 通过hash计算出来的值将会使用indexFor方法找到它应该所在的table下标: static int indexFor(int h, int length) { return h & (length-1); } 这个方法其实相当于对table.length取模。 当两个key通过

Java工具类——HashMap源码分析

风流意气都作罢 提交于 2020-02-29 02:51:46
1 /* 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20 * 21 * 22 * 23 * 24 */ 25 26 package java.util; 27 import java.io.*; 28 29 /** 30 * Hash table based implementation of the <tt>Map</tt> interface. This 31 * implementation provides all of the optional map operations, and permits 32 * <tt>null</tt> values and the <tt>null</tt> key. (The <tt>HashMap</tt> 33 * class is roughly equivalent to <tt>Hashtable</tt>, except

kotlin, how to put HashMap in Parcelable

核能气质少年 提交于 2020-02-28 19:03:20
问题 In a class who implements Parcelable it has a HashMap member. Saw Parcelable has public final void readMap(Map outVal, ClassLoader loader) , but could not find a sample to use it. If do it by flatten the map and write/read one by one accordingly, how to extract from the parcel in the constructor? (got error to build the map from the parcelable, cannot access buildTheMap() before constructor is called ) class CachedData(val type: Int, val name: String, val details: HashMap<String, String) :