Java类集---HasMap源码分析(resize和树化)HashtableTreeMap ConcurrentHashMap

本文深入剖析了Java中的HashMap,包括其内部结构、哈希计算、树化条件和扩容策略。同时,对比了线程不安全的HashMap与线程安全的Hashtable,讨论了ConcurrentHashMap的并发优化策略。HashMap在元素超过一定数量时会进行树化,以提升查找效率。文章还简要提及了TreeMap的排序特性。
摘要由CSDN通过智能技术生成

Map集合一次性会保存两个对象,即键值对。
Map集合:

public interface Map<K,V>

Key值唯一,通过一个key值能唯一找到一个value值。
Map接口的核心方法:

public V put(K key,V value) :向Map中添加数据
public V get (K key) :根据指定的key取得相应的vaule值,若没有此值,返回null
public Set<Map.Entry<K,V>> entrySet():将Map集合变为Set集合
public Set<K> keySet():返回所有Key值集合,key不能重复
public Collection<V> values( ):返回所有的vaule值,value可以重复

代码如下:

 public static void main(String[] args) {
   
        HashMap<Integer, String> map = new HashMap<>();
        map.put(2, "sophia");
        map.put(1, "pick");
        map.put(null, null);
        map.put(null, "happy");
        System.out.println(map); //{null=happy, 1=pick, 2=sophia}

        //通过key获取value
        System.out.println("key=1 value=" + map.get(1));
        System.out.println("key=null value=" + map.get(null)); //不允许重复,将值覆盖

        //获取key
        Set<Integer> set = map.keySet();
        System.out.println("所有的key:" + set); //所有的key:[null, 1, 2]

        //获取value
        Collection<String> list = map.values();
        System.out.println("所有的value"+list); //所有的value[happy, pick, sophia]

        //遍历map
        Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
        //方法一:取得entrySet的迭代器
        Iterator<Map.Entry<Integer,String>> iterator=entrySet.iterator();
        while(iterator.hasNext())
        {
   
            Map.Entry<Integer,String> entry=iterator.next();
            System.out.println(entry.getValue()+"="+entry.getKey()); //happy=null  pick=1  sophia=2
        }
        //方法2:for-each输出
        for (Map.Entry<Integer, String> entry : entrySet)
        {
   
            System.out.println(entry.getKey()+"->"+entry.getValue()); //null->happy   1->pick  2->sophia
        }
       
          //方法3:先找到所有的key,再根据key找value
        for(Integer key:map.keySet())
        {
   
            System.out.println(key+"="+map.get(key));  //null=happy  1=pick 2=sophia
        }
    }

Map集合有如下四个常用子类
HashMap TreeMap HashTable ConcurrentHashMap
1. HashMap
HashMap是Map最常用子类。

  • key可以为NULL;
  • value可以为NULL
  • key不可以重复,如果重复相当于覆盖
  • 线程不安全(不同步)
  • 在JDK8以前,底层实现是哈希表,JDK之后,底层是哈希表和红黑树。

HashMap源码分析:
HashMap的内部结构是数组(Node[ ] table)和链表组合而成的复合结构,数组被分为一个个桶,通过哈希值决定了键值对在这个数组的寻址,哈希值相同的键值对,则以链表形式存储。但是当达到一定条件后,会树化(红黑树)。
一:成员变量

DEFAULT_INITIAL_CAPACITY = 1 << 4;  桶的个数为162的次方)
MAXIMUM_CAPACITY = 1 << 30   桶的最大个数
DEFAULT_LOAD_FACTOR = 0.75f;   负载因子
TREEIFY_THRESHOLD = 8 (树化阈值,链表元素个数为8)
MIN_TREEIFY_CAPACITY = 64  哈希表元素个数(树化要求的最少哈希表元素个数)
UNTREEIFY_THRESHOLD= 6;  链表元素个数为6在resize阶段,解除树化阈值

二:初始化策略(懒加载策略,在第一次put初始化哈希表)

public HashMap() {
   
		//只是初始化负载因子
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
    }
public HashMap(int initialCapacity) {
   
    this(initialCapacity, DEFAULT_LOAD_FACTOR);
}

问题:要求哈希表初始化容量必须为2^n,若通过构造方法传入一个非2^n数值,
hashmap会在内部调用tableSizeFor返回一个距离最近的2^n数值,
传15返回16,传3132 100-<128

在HashMap的构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值