HashMap初始值、排序问题以及存储原理

HashMap在Java中提供了多种构造方法,如无参构造默认容量为16,加载因子为0.75。当元素达到一定数量时,容量会翻倍。HashMap本身不保证元素顺序,内部通过哈希值存储,非线程安全。若需排序,通常使用其有序子类LinkedHashMap。存储原理上,HashMap内部维护一个数组和链表,根据key的hash值确定存储位置,冲突时形成链表结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HashMap的初始值:
hashmap有多个构造方法,

  1. HashMap()
  2. HashMap(int initCapacity)
  3. HashMap(int initCapacity,float loadFactor)

第一个无参构造new出来的就是默认大小initCapacity为16个键值对,加载因子loadFactor为0.75的hashmap,即put到13时则将capacity翻倍。所以默认状态的map容量总是2的n次方;

第二个构造方法则可以设置默认大小

第三个还可以设置加载因子,注意是float类型。

HashMap排序问题

HashMap的排序是一个不怎么让人舒服的话题,因为HashMap存在的意义就是通过散列值排序,达到通过下标访问超快速的目的。
hashMap内部维护HashTable,但线程不同步,存储按照key计算的hash值进行排列。hashMap没有Comparator匿名内部类,因为会破坏按照hash值存储的顺序。只能通过Collections.sort(list,c)进行排列

Map<String,String> hashMap = new HashMap<String,String>();
        hashMap.put("bb", "baby");
        hashMap.put("aa", "angela");
        hashMap.put("dd", "david");
        hashMap.put("cc", "cendy");
        List<Map.Entry<String, String>> list2 = new ArrayList<Map.Entry<String,String>>(hashMap.entrySet());
        Collections.sort(list2, new Comparator<Map.Entry<String, String>>() {
            @Override
            public int compare(Entry<String, String> o1, Entry<String, String> o2) {
                return o1.getKey().compareTo(o2.getKey());
            }
        });
        for(Map.Entry<String, String> entry:list2){
            System.out.println(entry.getKey()+":"+entry.getValue());
        }

所以一般情况下使用其有序子类LinkedHashMap

HashMap存储原理

hashMap内部维护HashTable,相当于一个数组。
下面是put方法的源码
可以看出每次存入key与value,int hash = hash(key.hashCode());重新计算hash值
根据这个hash值得到此元素在数组中的位置(下标),并存入;
如果当前位置已经存在其他元素,则在当前位置以链表的形式存储这些值,新加入的在链头,之前加入的在链尾。

public V put(K key, V value) {  
    // HashMap允许存放null键和null值。  
    // 当key为null时,调用putForNullKey方法,将value放置在数组第一个位置。  
    if (key == null)  
        return putForNullKey(value);  
    // 根据key的keyCode重新计算hash值。  
    int hash = hash(key.hashCode());  
    // 搜索指定hash值在对应table中的索引。  
    int i = indexFor(hash, table.length);  
    // 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素。  
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {  
        Object k;  
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  
            V oldValue = e.value;  
            e.value = value;  
            e.recordAccess(this);  
            return oldValue;  
        }  
    }  
    // 如果i索引处的Entry为null,表明此处还没有Entry。  
    modCount++;  
    // 将key、value添加到i索引处。  
    addEntry(hash, key, value, i);  
    return null;  
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值