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是线程安全
随机推荐
- LCS(打印路径) POJ 2250 Compromise
题目传送门 题意:求单词的最长公共子序列,并要求打印路径 分析:LCS 将单词看成一个点,dp[i][j] = dp[i-1][j-1] + 1 (s1[i] == s2[j]), dp[i][j] ...
- 打包apk
apk 配置环境变量 打开"终端",输入"pico .bash_profile"命令 export ANDROID_SDK_ROOT=/Users/sun/Do ...
- unity button
#pragma strict var buttonTexture:Texture2D; private var str:String; private var frameTime:int; funct ...
- POJ 1064 (二分)
题目链接: http://poj.org/problem?id=1064 题目大意:一堆棍子可以截取,问要求最后给出K根等长棍子,求每根棍子的最大长度.保留2位小数.如果小于0.01,则输出0.00 ...
- 【SPOJ】1825. Free tour II(点分治)
http://www.spoj.com/problems/FTOUR2/ 先前看了一会题解就自己yy出来了...对拍过后交tle.................. 自己造了下大数据........t ...
- php如何判断远程文件是否存在
<?php /* 函数:remote_file_exists 功能:判断远程文件是否存在 参数: $url_file -远程文件URL 返回:存在返回true,不存在或者其他原因 ...
- 如何在URL筛选管理器中过滤不需要的URL
互联网可以说是一把名副其实的双刃剑.一方面其可以提高工作效率.给企业提供充分的资源;另一方面如果管理不严,也会带来很多的隐患.如员工在上班时间玩游戏.炒股等等.为此现在很多企业希望对员工的网络行为进行 ...
- php的源代码包构建一个空的php扩展。
下载一个php的源代码包,这里使用的是php 4.0.5版,解压后会看到php的根目录下会有README.EXT_SKEL这样一个文件,打开详细阅读了一下,发现了一个非常好用的工具,这个工具可以帮你构 ...
- 《GK101任意波发生器》升级固件发布(版本:1.0.2build851)
一.固件说明: 硬件版本:0,logic.3 固件版本:1.0.2.build851 编译日期:2015-06-26 ====================================== 二. ...
- metasploit--exploit模块信息
Name Disclosure Date Rank Description ---- ...