常见数据结构在内存中是怎么存储的

三人行,必有吾师,欢迎加入星球,一起讨论技术点滴

前言:

在开发中,经常用到数组,ArrayList,HashMap等,他们在内存中是怎么存储的呢?
其实在他们在申请内存时,要么是一块连续的内存,要么是分散的,要么是内存和连续的结合使用。说白了在底层存储结构只有两种:数组和链表;
数组是连续的,只要知道了首地址,就可以通过步长访问数组内所有的值,如果arraylist是基于数组的。
链表是分散的,每个位置除了包含值还会包含下一项的指针,双向链表会前后两项的指针。

ArrayList

ArrayList底层是基于数组存储的,相对于数组,arraylist可以动态扩容(使用数组时,在定义时,需要指定长度,但arrayList不需要)。
所以arrayList中存储是连续的,查询会很方便。但删除插入时,除非是尾部,否则都会涉及到其他位置的重新赋值,影响效率。
ArrayList的动态扩容,定义arraylist时,如果没有定义长度,默认的长度是10 可能不同换jdk有不同的实现,当需要扩容时,会申请一块原size 1.5倍的内存块(new_size=old_size+old_size>>1),然后将原内存块中的内容复制到新的内存块中。原内存块清空,从而实现扩容。

LinkedList

 linkedList 底层是基于 链表的,每个结点,都会有前一个和下一个的指针,插入删除,也只需要改变指针指向的位置就可以了。

hashMap

 hashmap 是基于数组和链表的,hashMap 默认申请大小为16 的数组,当存储时,根据key的hashCode,决定存储在数组中的第几个索引,如果该索引已经存储了其他元素,刚判断两个key是否相等,如果相等,刚覆盖,否则存储在该索引处的链表中。
 hashMap扩容时,也需要重新申请一块连续的内存,将原内存块内容复制到新的内存块中,但是个索引处的链表节点,不需要重新创建。
 hashMap 扩容机制:默认长度是16 如果需要扩容则扩为原来的2倍。

你可能感兴趣的:(Java基础知识)