源码调试 --map篇--HashMap

HashMap:

hashmap的一些参数默认初始值:
DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16  默认初始容量:16
MAXIMUM_CAPACITY = 1 << 30;  默认最大容量:10亿多
DEFAULT_LOAD_FACTOR = 0.75f;   默认负载因子:0.75 ???有什么用?
TREEIFY_THRESHOLD = 8;  默认阈值阈值:8  
UNTREEIFY_THRESHOLD = 6;     默认取消阈值:6
MIN_TREEIFY_CAPACITY = 64;     默认最小存储容量:64
/**
 * The next size value at which to resize (capacity * load factor).当前阈(yù)值(达到该值,则进行扩容)
 *
 * @serial
 */
int threshold;

 阈值:12 24 48 96

总的容量:16 32 64 128

int modCount;  记录map修改次数

数组:

/**
 * The table, initialized on first use, and resized as
 * necessary. When allocated, length is always a power of two.
 * (We also tolerate length zero in some operations to allow
 * bootstrapping mechanics that are currently not needed.)
 */
transient Node<K,V>[] table;

结构体(链表):

static class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    V value;
    Node<K,V> next;

    Node(int hash, K key, V value, Node<K,V> next) {
        this.hash = hash;
        this.key = key;
        this.value = value;
        this.next = next;
    }

(二叉树):

/**
 * Entry for Tree bins. Extends LinkedHashMap.Entry (which in turn
 * extends Node) so can be used as extension of either regular or
 * linked node.
 */
static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
    TreeNode<K,V> parent;  // red-black tree links
    TreeNode<K,V> left;
    TreeNode<K,V> right;
    TreeNode<K,V> prev;    // needed to unlink next upon deletion
    boolean red;

put方法:

  首先计算key的hash值:

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

^:异或,相同为0,不同为1;

if (++size > threshold)//判断,当前长度+1  与  容量*偏移量的值的大小
    resize();//
afterNodeInsertion(evict);//将值保存在hashmapentryset类属性中。
遍历录入 <KEY,VALUE>
/**
 * Holds cached entrySet(). Note that AbstractMap fields are used
 * for keySet() and values().
 */
transient Set<Map.Entry<K,V>> entrySet;  

可以放 <null,null>

判断是否需要扩张成红黑树 操作

binCount:数组后跟的链表大小
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) // -1 for 1st
                treeifyBin(tab, hash);// 桶装不下,则查看是否需要扩张成红黑树
            break;
        }
        if (e.hash == hash &&
            ((k = e.key) == key || (key != null && key.equals(k))))
            break;
        p = e;
    }
}
/**
 * Replaces all linked nodes in bin at index for given hash unless
 * table is too small, in which case resizes instead. 当桶的大小超过8,且hash表数组长度大于等于 64  ===》链表转二叉树
 */
final void treeifyBin(Node<K,V>[] tab, int hash) {
if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
    resize();
else if ((e = tab[index = (n - 1) & hash]) != null) {

remove:

/**
 * Implements Map.remove and related methods.
 *
 * @param hash hash for key
 * @param key the key
 * @param value the value to match if matchValue, else ignored
 * @param matchValue if true only remove if value is equal
 * @param movable if false do not move other nodes while removing
 * @return the node, or null if none
 */
final Node<K,V> removeNode(int hash, Object key, Object value,
                           boolean matchValue, boolean movable)

(p = tab[index = (n - 1) & hash]) != null) {//怎么算出key所在位置???

/**
 * Replaces all linked nodes in bin at index for given hash unless
 * table is too small, in which case resizes instead. 当桶的大小超过8,且当前hash表数组长度大于等于 64  ===》链表转二叉树
 */
final void treeifyBin(Node<K,V>[] tab, int hash) 

LinkedHashMap:


  class LinkedHashMap<K,V>
    extends HashMap<K,V>
    所以  很多方法都是使用的 HashMap的方法。

```java
/**
     * HashMap.Node subclass for normal LinkedHashMap entries.
     * 双向双链表结构
     */
    static class Entry<K,V> extends HashMap.Node<K,V> {
        Entry<K,V> before, after;
        Entry(int hash, K key, V value, Node<K,V> next) {
            super(hash, key, value, next);
        }
    }
```

线程不安全

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值