Java HashMap、LinkedHashMap
如果需要使用的Map中的key无序,选择HashMap;如果要求key有序,则选择TreeMap。
但是选择TreeMap就会有性能问题,因为TreeMap的get操作的时间复杂度是O(log(n))的,
相比于HashMap的O(1)还是差不少的,LinkedHashMap的出现就是为了平衡这些因素,使得
能够以
O(1)时间复杂度增加查找元素,又能够保证key的有序性
此外,LinkedHashMap提供了两种key的顺序:
- 访问顺序(access order)。非常实用,可以使用这种顺序实现LRU(Least Recently Used)缓存
- 插入顺序(insertion orde)。同一key的多次插入,并不会影响其顺序
一。HashMap
1.HashMap构造函数
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " + loadFactor);
this.loadFactor = loadFactor;
threshold = initialCapacity;
init(); //注意这个模板函数,在LinkHashMap中有使用
}
2.默认参数
//容量必须为2的指数(默认为16),想想原因?
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; static final int MAXIMUM_CAPACITY = 1 << 30; //默认的平衡因子为0.75,这是权衡了时间复杂度与空间复杂度之后的取值
//过高的因子可以增加存储空间利用率但是查找的时间就会增加。
static final float DEFAULT_LOAD_FACTOR = 0.75f;
3.重设索引
void resize(int newCapacity) {
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return;
}
Entry[] newTable = new Entry[newCapacity];
transfer(newTable, initHashSeedAsNeeded(newCapacity));
table = newTable;
threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
}
/**
* Transfers all entries from current table to newTable.
*/
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;
}
}
}
4.
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);
}
二。LinkedHashMap
1.Entry
private static class Entry<K,V> extends HashMap.Entry<K,V> {
// These fields comprise the doubly linked list used for iteration.
Entry<K,V> before, after;
Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
super(hash, key, value, next);
}
}
2.删除
//删除一个节点时,需要把
//1. 前继节点的后继指针 指向 要删除节点的后继节点
//2. 后继节点的前继指针 指向 要删除节点的前继节点
private void remove() {
before.after = after;
after.before = before;
}

3.增加
private void addBefore(Entry<K,V> existingEntry) {
after = existingEntry; //当前节点的后继节点 指向 新节点
before = existingEntry.before; //
before.after = this; //
after.before = this; //
}

4.重写的init
@Override
void init() {
header = new Entry<>(-1, null, null, null);
header.before = header.after = header;
}
5.重写transfer
/**
* Transfers all entries to new table array. This method is called
* by superclass resize. It is overridden for performance, as it is
* faster to iterate using our linked list.
*/
@Override
void transfer(HashMap.Entry[] newTable, boolean rehash) {
int newCapacity = newTable.length;
for (Entry<K,V> e = header.after; e != header; e = e.after) { //把链表里的元素重排序
if (rehash)
e.hash = (e.key == null) ? 0 : hash(e.key);
int index = indexFor(e.hash, newCapacity);
e.next = newTable[index];
newTable[index] = e;
}
}
Java HashMap、LinkedHashMap的更多相关文章
- [Java] HashMap、TreeMap、Hashtable排序
Java中对Map(HashMap,TreeMap,Hashtable等)的排序时间 首先简单说一下他们之间的区别: HashMap: 最常用的Map,它根据键的HashCode 值存储数据,根据键可 ...
- HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList 底层实现
HashMap相关问题 1.你用过HashMap吗?什么是HashMap?你为什么用到它? 用过,HashMap是基于哈希表的Map接口的非同步实现,它允许null键和null值,且HashMap依托 ...
- HashMap、LinkedHashMap和TreeMap对比
共同点: HashMap,LinkedHashMap,TreeMap都属于Map:Map 主要用于存储键(key)值(value)对,根据键得到值,因此键不允许键重复,但允许值重复. 不同点: 1.H ...
- HashMap 、LinkedHashMap、HashTable、TreeMap 和 Properties 的区别
HashMap 1.线程不安全: 2.允许null value 和 null key: 3.访问效率比较高: 4.Java1.2引进的Map接口的一个实现: 5.轻量级: 6.根据键的HashCode ...
- java HashMap和LinkedHashMap区别
我们用的最多的是HashMap,在Map 中插入.删除和定位元素,HashMap 是最好的选择.但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好.如果需要输出的顺序和输入的相同,那么用 ...
- 对比分析HashMap、LinkedHashMap、TreeMap
HashMap的原理 :简单地说,HashMap 在底层将 key-value 当成一个整体进行处理,这个整体就是一个 Entry 对象.HashMap 底层采用一个 Entry[] 数组来保存所有的 ...
- Java HashMap、HashTable与ConCurrentHashMap
一.Java中数据存储方式最底层的两种结构 1.数组:存储空间连续,寻址迅速,增删较慢.(代表:ArrayList) 2.链表:存储空间不连续,寻址慢,增删较快.(代表:LinkedList) 二.哈 ...
- HashTable、HashMap、LinkedHashMap、TreeMap的比较
HashTable:继承自Dictionary类,实现了Map接口,不允许键或值为空,线程同步: HashMap:继承自AbstractMap类,实现了Map接口,允许键或值为空,线程不同步: Lin ...
- Java HashMap、HashTable、TreeMap、WeakHashMap区别
1.HashMap不是线程安全,而HashTable是线程安全
随机推荐
- Codeforces 86D Powerful array(莫队算法)
和BZOJ2038差不多..复习一下. #include<cstdio> #include<cmath> #include<algorithm> using nam ...
- BZOJ1707 : [Usaco2007 Nov]tanning分配防晒霜
S向每头奶牛连边,容量1 每个防晒霜向T连边,容量cover 每头奶牛向SPF在自己范围内的防晒霜连边,容量inf 用线段树优化建图跑最大流即可. #include<cstdio> con ...
- 【BZOJ】3196: Tyvj 1730 二逼平衡树(区间第k小+树套树)
http://www.lydsy.com/JudgeOnline/problem.php?id=3196 Treap+树状数组 1WA1A,好伤心,本来是可以直接1A的,这次开始我并没有看题解,就写出 ...
- ubuntu14.04美化
首先我美化grub启动菜单背景和开关机背景,还有自动换壁纸.其它的美化日后再写博文. Grub启动菜单背景更换: 这个很简单,比以前的ubuntu和grub版本简单多了,直接将图片文件放到/boot/ ...
- oracle系列--第五篇 PLSQL连接本地的Oracle数据库
这篇blog主要是针对新手,我也是个新手:) 我们把oracle成功的安装在了我们的计算机上面,那我们如何才能将PLSQL developer连 接到本地的oracle呢? 首先,我们必须有下面步准备 ...
- 什么是J2EE,包括哪些规范!
J2EE平台由一整套服务(Services).应用程序接口(APIs)和协议构成,它对开发基于Web的多层应用提供了功能支持,下面对J2EE中的13种技术规范进行简单的描述(限于篇幅,这里只能进行简单 ...
- mysql 商品表的设计思路(面向对象建表:类与对象)
学习地址 http://www.jtthink.com/course/play/352 商品通用信息主表:prop_main 不仔细多说,正常业务都会涉及到并且考虑的相对周全.常用字段[商品id][商 ...
- Html - 幽灵键盘
Css ;text-align:center} #shurufa_gongneng,#shurufa_num_123,#shurufa_num_456,#shurufa_num_789{} #shur ...
- java ---运算符
运算符简单来划分可以分为五大类:分别是算术运算符.关系运算符.逻辑运算符.三元运算符和赋值运算符.下面来分别介绍一下这几类运算符: 一.算术运算符 包含+ - * / % ++ --,这几 ...
- IOS第四天(5:创建备份区按钮和判断结果)
创建备份区按钮和判断结果 /** 创建备选区按钮 */ - (void)createOptionButtons:(HMQuestion *)question { // 问题:每次调用下一题方法时,都会 ...