hashmap

HashMap的put get最简单实现

人走茶凉 提交于 2020-04-06 05:54:51
public class MyHashMap<K,V> { class Entry<K,V>{ private K k; private V v; private Entry<K,V> next; Entry(K k, V v, Entry<K, V> next) { this.k = k; this.v = v; this.next = next; } } Entry<K,V> tables[]; private int CAPACITY=8; private int size=0; public MyHashMap(){ tables=new Entry[CAPACITY]; } public Object put(K k,V v){ int hash = k.hashCode(); int i=hash%8; for(Entry<K,V> entry=tables[i];entry!=null;entry=entry.next){ if(k==entry.k){ V oldValue= entry.v; entry.v=v; return oldValue; } } addEntry(i,k,v); return null; } private void addEntry(int i, K k, V v) { Entry<K,V> entry =new Entry<>(k,v

HashMap在Java1.7与1.8中的区别

风流意气都作罢 提交于 2020-04-06 00:24:23
基于 JDK1.7.0_80 与 JDK1.8.0_66 做的分析 JDK1.7中 使用一个Entry数组来存储数据,用key的hashcode取模来决定key会被放到数组里的位置,如果hashcode相同,或者hashcode取模后的结果相同(hash collision),那么这些key会被定位到Entry数组的同一个格子里,这些key会形成一个链表。 在hashcode特别差的情况下,比方说所有key的hashcode都相同,这个链表可能会很长,那么put/get操作都可能需要遍历这个链表 也就是说时间复杂度在最差情况下会退化到O(n) JDK1.8中 使用一个Node数组来存储数据,但这个Node可能是链表结构,也可能是红黑树结构 如果插入的key的hashcode相同,那么这些key也会被定位到Node数组的同一个格子里。 如果同一个格子里的key不超过8个,使用链表结构存储。 如果超过了8个,那么会调用treeifyBin函数,将链表转换为红黑树。 那么即使hashcode完全相同,由于红黑树的特点,查找某个特定元素,也只需要O(log n)的开销 也就是说put/get的操作的时间复杂度最差只有O(log n) 听起来挺不错,但是真正想要利用JDK1.8的好处,有一个限制: key的对象,必须 正确的实现了Compare接口 如果没有实现Compare接口

Java HashMap 扩容过程分析

放肆的年华 提交于 2020-04-02 23:33:12
1 final Node<K, V> resize(){ 2 3 // 用于存储重新散列后的数组 4 Node<K, V>[] newTab; 5 6 // 如果原来的数组是空的,则resize执行的是初始化操作,而不是扩容操作 7 if(table == null){ 8 // 初始容量为16 9 int cap = DEFAULT_CAPACITY;// 1<<<4 10 11 // 初始的加载因子为0.75,即容量使用到3/4时就要再次扩容 12 loadFactor = DEFAULT_LOADFACTOR; 13 14 // 设置扩容阈值 15 threshold = (int)(cap * loadFactor); 16 17 newTab = (Node<K, V>[])(new Node[cap]); 18 return newTab; 19 } 20 21 // ... 省略了细节处理,例如容量到达最大值时应该怎么办,本程序段主要讲述扩容流程 22 23 // 如果原来的数组不为空,则先扩容,再把原来的数据重新散列到新的扩容后的数组中 24 int oldCap = table.length; 25 int newCap = oldCap << 1; 26 threshold = newCap * loadFactor; 27 newTab = (Node<K,

java集合之Map接口

时光怂恿深爱的人放手 提交于 2020-04-02 05:12:51
一、Map的实现类大概结构: ---Map:双列数据,存储key-value对的数据(类似于高中的函数)   ---HashMap:作为Map的主要实现类;线程不安全,效率高。可以存储null的key和value     ---LinkedHashMap:作为HashMap的子类,保证在遍历map元素时,可以按照添加的顺序实现遍历。因为它在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个。对于频繁的遍历操作,此类执行效率高于HashMap。   ---TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序。底层使用红黑树。   ---Hashtable:作为古老的实现类,比Map还早,1.0就有。线程安全的,效率低。不可以存储null的key和value。     ---Properties:常用来处理配置文件。key和value都是String类型 HashMap的底层:数组+链表(JDK7.0及之前)          数组+链表+红黑树(JDK8.0) 二、Map结构的理解: Map中的key:无序的、不可重复的,使用set存储所有的key。——>key所在类要重写equals()和hashCode()。 Map中的value:无序的、可重复的,使用Collection存储所有的value。——

ava集合---HashSet的源码分析

妖精的绣舞 提交于 2020-04-01 06:15:22
一、HasnSet概述    Hashset实现set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set的迭代顺序。特别是它不保证该顺序恒久不变。此类允许使用Null元素 一、HasnSet的实现    对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet的实现比较简单,相关HashSet的操作,基本上都说调用HashMap的相关方法来实现的   HashSet的源代码如下    public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable 4{ static final long serialVersionUID = -5024744406713321676L; // 底层使用HashMap来保存HashSet中所有元素。 private transient HashMap<E,Object> map; // 定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。 private static final Object PRESENT = new Object(); /** * 默认的无参构造器

java集合--collection集合

寵の児 提交于 2020-03-31 06:40:17
1、画出collection的框架图   集合主要包含collection和map两个接口。其中collection中的元素是一个value值,map中的元素是key:value形式的。   collection包含set、list、queue。     (1)list:list接口包含ArrayList,Vector,LinkedList。     (2)set包含HashSet,TreeSet,EnumSet。     (3)Queueu包含LinkedList,PriorityQueue   map包含HashMap,HashTable,TreeMap,WeakHashMap,IdentityHashMap,EnumMap 2、详述List、Map、Set的区别?(底层实现的数据结构不同)   (1)List:有序,可重复。     ArrayList:底层实现的数据结构是数组,查询快,增删慢。线程不安全,效率高     LinkedList:底层实现的数据结构是链表,查询慢,增删块。线程不安全,效率高     Vector:底层实现的数据结构是数组,查绚块,增删慢。线程安全,效率低。   (2)Set:无序,唯一。     HashSet:底层数据结构是哈希表(无序,唯一)。保证元素唯一性依赖于两个方法:hashCode()和equals()    

JAVA 面试须知

这一生的挚爱 提交于 2020-03-30 18:21:31
本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺。 1. Java中的原始数据类型都有哪些,它们的大小及对应的封装类是什么? (1)boolean boolean数据类型非true即false。这个数据类型表示1 bit的信息,但是它的大小并没有精确定义。 《Java虚拟机规范》中如是说:“虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,每个元素boolean元素占8位”。这样我们可以得出boolean类型单独使用是4个字节,在数组中又是1个字节。那虚拟机为什么要用int来代替boolean呢?为什么不用byte或short,这样不是更节省内存空间吗?实际上,使用int的原因是,对于当下32位的CPU来说,一次进行32位的数据交换更加高效。 综上,我们可以知道:官方文档对boolean类型没有给出精确的定义,《Java虚拟机规范》给出了“单独时使用4个字节,boolean数组时1个字节”的定义,具体还要看虚拟机实现是否按照规范来

java基础面试题 整理给自己

ぃ、小莉子 提交于 2020-03-30 16:37:44
基础内容 1.JDK 和 JRE 有什么区别? JDK提供了java的开发环境和运行环境,JRE只是java的运行环境。JDK除了包含JRE还包含了编译器javac以及一些java程序的分析调试工具。 2.== 和 equals 的区别是什么? == 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引用比较,只是很多类重写了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。 3. 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗? 不对,两个对象的 hashCode()相同,equals()不一定 true。 有些字符串的hashCode 可能一样 4.final 在 java 中有什么作用? final修饰的类是最终类不能被继承;final修饰的方法不能被重写;final修饰的变量是常量,必须初始化,初始化后不能被修改。 5.java 的基本类型 基础类型有 8 种:byte、boolean、char、short、int、float、long、double 6. java 中操作字符串都有哪些类?它们之间有什么区别? 操作字符串的类有:String、StringBuffer、StringBuilder。 String 和

Java面试知识点总结

纵饮孤独 提交于 2020-03-30 16:09:29
Java面试知识点总结 本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺(阅读本文需要有一定的Java基础;若您初涉Java,可以通过这些问题建立起对Java初步的印象,待有了一定基础后再后过头来看收获会更大)。本文的问题列表来自于http://www.nowcoder.com/discuss/3043,在此感谢原作者的无私分享:) 1. Java中的原始数据类型都有哪些,它们的大小及对应的封装类是什么? (1)boolean boolean数据类型非true即false。这个数据类型表示1 bit的信息,但是它的大小并没有精确定义。 《Java虚拟机规范》中如是说:“虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,每个元素boolean元素占8位”。这样我们可以得出 boolean类型单独使用是4个字节,在数组中又是1个字节。 那虚拟机为什么要用int来代替boolean呢?为什么不用byte或short,这样不是更节省内存空间吗

Java集合框架(List,Set,Map)

♀尐吖头ヾ 提交于 2020-03-30 12:08:51
单列集合基本框架 List接口特点: 1. 它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)。 2. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。 3. 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。 4.List 接口提供了特殊的迭代器,称为 ListIterator ,除了允许 Iterator 接口提供的正常操作外,该迭代器还允许元素插入和替换,以及双向访问。还提供了一个方法来获取从列表中指定位置开始的列表迭代器。 List接口常用实现类: ## vector集合 Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。 由 Vector 的 iterator 和 listIterator 方法所返回的迭代器是快速失败的 特点:1.线程同步的2.底层是数组实现的 特有方法 Enumeration<E> elements() ##ArrayList集合 1.底层是数组实现的 2.不是线程同步的 3.查询比较快 java.util.ArrayList`集合数据存储的结构是数组结构。方便元素随机访问。 ## LinkedList集合 1.底层是一个链表实现的 2.不同步。线程不安全 3