默认值
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4 ;
static final int MAXIMUM_CAPACITY = 1 << 30 ;
static final float DEFAULT_LOAD_FACTOR = 0.75f ;
static final int TREEIFY_THRESHOLD = 8 ;
static final int UNTREEIFY_THRESHOLD = 6 ;
static final int MIN_TREEIFY_CAPACITY = 64 ;
带有初始化容量和负载因子
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;
this . threshold = tableSizeFor ( initialCapacity) ;
}
带有初始化容量
public HashMap ( int initialCapacity) {
this ( initialCapacity, DEFAULT_LOAD_FACTOR) ;
}
无参构造
public HashMap ( ) {
this . loadFactor = DEFAULT_LOAD_FACTOR;
}
传入map的构造
public HashMap ( Map < ? extends K , ? extends V > m) {
this . loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries ( m, false ) ;
}
tableSizeFor()
static final int tableSizeFor ( int cap) {
int n = cap - 1 ;
n |= n >>> 1 ;
n |= n >>> 2 ;
n |= n >>> 4 ;
n |= n >>> 8 ;
n |= n >>> 16 ;
return ( n < 0 ) ? 1 : ( n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1 ;
}
hash
static final int hash ( Object key) {
int h;
return ( key == null ) ? 0 : ( h = key. hashCode ( ) ) ^ ( h >>> 16 ) ;
}
put方法
public V put ( K key, V value) {
return putVal ( hash ( key) , key, value, false , true ) ;
}
putVal
final V putVal ( int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node < K , V > [ ] tab;
Node < K , V > p;
int n, i;
if ( ( tab = table) == null || ( n = tab. length) == 0 )
n = ( tab = resize ( ) ) . length;
if ( ( p = tab[ i = ( n - 1 ) & hash] ) == null )
tab[ i] = newNode ( hash, key, value, null ) ;
else {
Node < K , V > e;
K k;
if ( p. hash == hash &&
( ( k = p. key) == key || ( key != null && key. equals ( k) ) ) )
e = p;
else if ( p instanceof TreeNode )
e = ( ( TreeNode < K , V > ) p) . putTreeVal ( this , tab, hash, key, value) ;
else {
for ( int binCount = 0 ; ; ++ binCount) {
if ( ( e = p. next) == null ) {
p. next = newNode ( hash, key, value, null ) ;
if ( binCount >= TREEIFY_THRESHOLD - 1 )
treeifyBin ( tab, hash) ;
break ;
}
if ( e. hash == hash &&
( ( k = e. key) == key || ( key != null && key. equals ( k) ) ) )
break ;
p = e;
}
}
if ( e != null ) {
V oldValue = e. value;
if ( ! onlyIfAbsent || oldValue == null )
e. value = value;
afterNodeAccess ( e) ;
return oldValue;
}
}
++ modCount;
if ( ++ size > threshold)
resize ( ) ;
afterNodeInsertion ( evict) ;
return null ;
}
resize()
final Node < K , V > [ ] resize ( ) {
Node < K , V > [ ] oldTab = table;
int oldCap = ( oldTab == null ) ? 0 : oldTab. length;
int oldThr = threshold;
int newCap, newThr = 0 ;
if ( oldCap > 0 ) {
if ( oldCap >= MAXIMUM_CAPACITY) {
threshold = Integer . MAX_VALUE;
return oldTab;
}
else if ( ( newCap = oldCap << 1 ) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1 ;
}
else if ( oldThr > 0 )
newCap = oldThr;
else {
newCap = DEFAULT_INITIAL_CAPACITY;
newThr = ( int ) ( DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY) ;
}
if ( newThr == 0 ) {
float ft = ( float ) newCap * loadFactor;
newThr = ( newCap < MAXIMUM_CAPACITY && ft < ( float ) MAXIMUM_CAPACITY ?
( int ) ft : Integer . MAX_VALUE) ;
}
threshold = newThr;
@SuppressWarnings ( { "rawtypes" , "unchecked" } )
Node < K , V > [ ] newTab = ( Node < K , V > [ ] ) new Node [ newCap] ;
table = newTab;
if ( oldTab != null ) {
for ( int j = 0 ; j < oldCap; ++ j) {
Node < K , V > e;
if ( ( e = oldTab[ j] ) != null ) {
oldTab[ j] = null ;
if ( e. next == null )
newTab[ e. hash & ( newCap - 1 ) ] = e;
else if ( e instanceof TreeNode )
( ( TreeNode < K , V > ) e) . split ( this , newTab, j, oldCap) ;
else {
Node < K , V > loHead = null , loTail = null ;
Node < K , V > hiHead = null , hiTail = null ;
Node < K , V > next;
do {
next = e. next;
if ( ( e. hash & oldCap) == 0 ) {
if ( loTail == null )
loHead = e;
else
loTail. next = e;
loTail = e;
}
else {
if ( hiTail == null )
hiHead = e;
else
hiTail. next = e;
hiTail = e;
}
} while ( ( e = next) != null ) ;
if ( loTail != null ) {
loTail. next = null ;
newTab[ j] = loHead;
}
if ( hiTail != null ) {
hiTail. next = null ;
newTab[ j + oldCap] = hiHead;
}
}
}
}
}
return newTab;
}
treeifBin
final void treeifyBin ( Node < K , V > [ ] tab, int hash) {
int n, index; Node < K , V > e;
if ( tab == null || ( n = tab. length) < MIN_TREEIFY_CAPACITY)
resize ( ) ;
else if ( ( e = tab[ index = ( n - 1 ) & hash] ) != null ) {
TreeNode < K , V > hd = null , tl = null ;
do {
TreeNode < K , V > p = replacementTreeNode ( e, null ) ;
if ( tl == null )
hd = p;
else {
p. prev = tl;
tl. next = p;
}
tl = p;
} while ( ( e = e. next) != null ) ;
if ( ( tab[ index] = hd) != null )
hd. treeify ( tab) ;
}
}
普通Node
final int hash;
final K key;
V value;
Node < K , V > next;
树化后的Node
TreeNode < K , V > parent;
TreeNode < K , V > left;
TreeNode < K , V > right;
TreeNode < K , V > prev;
boolean red;
get
public V get ( Object key) {
Node < K , V > e;
return ( e = getNode ( hash ( key) , key) ) == null ? null : e. value;
}
getNode
final Node < K , V > getNode ( int hash, Object key) {
Node < K , V > [ ] tab;
Node < K , V > first, e;
int n; K k;
if ( ( tab = table) != null && ( n = tab. length) > 0 &&
( first = tab[ ( n - 1 ) & hash] ) != null ) {
if ( first. hash == hash &&
( ( k = first. key) == key || ( key != null && key. equals ( k) ) ) )
return first;
if ( ( e = first. next) != null ) {
if ( first instanceof TreeNode )
return ( ( TreeNode < K , V > ) first) . getTreeNode ( hash, key) ;
do {
if ( e. hash == hash &&
( ( k = e. key) == key || ( key != null && key. equals ( k) ) ) )
return e;
} while ( ( e = e. next) != null ) ;
}
}
return null ;
}
remove
public V remove ( Object key) {
Node < K , V > e;
return ( e = removeNode ( hash ( key) , key, null , false , true ) ) == null ?
null : e. value;
}
removeNode
final Node < K , V > removeNode ( int hash, Object key, Object value,
boolean matchValue, boolean movable) {
Node < K , V > [ ] tab;
Node < K , V > p;
int n, index;
if ( ( tab = table) != null && ( n = tab. length) > 0 &&
( p = tab[ index = ( n - 1 ) & hash] ) != null ) {
Node < K , V > node = null , e; K k; V v;
if ( p. hash == hash &&
( ( k = p. key) == key || ( key != null && key. equals ( k) ) ) )
node = p;
else if ( ( e = p. next) != null ) {
if ( p instanceof TreeNode )
node = ( ( TreeNode < K , V > ) p) . getTreeNode ( hash, key) ;
else {
do {
if ( e. hash == hash &&
( ( k = e. key) == key ||
( key != null && key. equals ( k) ) ) ) {
node = e;
break ;
}
p = e;
} while ( ( e = e. next) != null ) ;
}
}
if ( node != null && ( ! matchValue || ( v = node. value) == value ||
( value != null && value. equals ( v) ) ) ) {
if ( node instanceof TreeNode )
( ( TreeNode < K , V > ) node) . removeTreeNode ( this , tab, movable) ;
else if ( node == p)
tab[ index] = node. next;
else
p. next = node. next;
++ modCount;
-- size;
afterNodeRemoval ( node) ;
return node;
}
}
return null ;
}