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是线程安全
随机推荐
- 在Linux下搭建SVN服务器
svn不仅仅可以用于程序开发,还可以做很多事情,例如备份文档. CentOS下:安装 这样同一台服务器便可以运行多个svnserver了 检查端口 注:如果修改了svn配置,需要重启svn服务 -j ...
- Spring AOP 详解
AOP使用场景 AOP用来封装横切关注点,具体可以在下面的场景中使用: Authentication 权限 Caching 缓存 Context passing 内容传递 Error handling ...
- SU suspecfk命令学习
用suplane生成平面,并查看其FK谱, 水平反射界面经FK变换后,波数为0, 正好处于临界,乃奎斯特频率, 有空间假频, Over,不足之处,欢迎批评指正.
- VC创建预编译文件
Building a simple "hello world" Ogre application can take several seconds on a modern mach ...
- Counting Squares[HDU1264]
Counting Squares Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- extjs 2.0获取选中的radio的值
var temp=winFormPanel.getForm().findField('selectedType').getGroupValue();
- c# windows service
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Hadoop虽然强大,但不是万能的(CSDN)
Hadoop很强大,但企业在使用Hadoop或者大数据之前,首先要明确自己的目标,再确定是否选对了工具,毕竟Hadoop不是万能的!本文中列举了几种不适合使用Hadoop的场景. 随着 Hadoop ...
- iOS开发Swift篇—简单介绍
iOS开发Swift篇—简单介绍 一.简介 Swift是苹果于2014年WWDC(苹果开发者大会)发布的全新编程语言 Swift在天朝译为“雨燕”,是它的LOGO 是一只燕子,跟Objective-C ...
- C++ unordered_map remove 实现哈希表移除
使用C++的unordered_map类型时,我们经常要根据关键字查找,并移除一组映射,在Java中直接用remove即可,而STL中居然没有实现remove这个函数,还要自己写循环来查找要删除项,然 ...