HashMap的key应该这么选择

不应该使用数组作为HashMap的key

原因分析:

HashMap有比较两个key是否相同的需要,并且hashMap是通过hashCode来判断key是否相同的.
数组的hashCode:数组的hashCode是以其地址作为依据,而并非数组的内容作为依据.
这就导致及时两个数组的内容是一样的,但是因为其地址不同,所以其hashCode还是不同,因此当两个相同的数组放入到hashMap中,不会覆盖,而是放入两个"不同"的key-value对象.

“不同”:指hashMap认为他们是不同的.

综上所述,使用数组作为HashMap的key不能得到我们想要的结果.
让我们看看代码:

import java.util.HashMap;

public class Main {
    public static void main(String[] args){
        int[] array1={1,2,3,4};
        int[] array2={1,2,3,4};

        HashMap<int[],String> map = new HashMap<>();
        System.out.println("the hashmap's size "+map.size());

        map.put(array1,"this is the array1");
        System.out.println("after added array1,the hashmap's size "+map.size());

        map.put(array2,"this is the array2");
        System.out.println("after added array2,the hashmap's size "+map.size());
    }
}

在这里插入图片描述
我们可以看到输出,即尽管array1和array2中的元素都一样,但是hashmap还是将它们看作是同一个key,因此添加了两个.

解决方案:

但是我们还是希望对这个数组的对象使用HashMap的功能.

  1. 将数组转化为String作为key
    在这里插入图片描述

  2. 使用List代替数组作为key
    在这里插入图片描述

关于hashMap的其他注意点:

  • 最好不要用Object作为HashMap的key
  • 如果要使用,需要覆写equals和hashCode方法,并适当简单
  • HashMap是线程不安全的,java提供了线程安全的版本ConcurrentHashMap

HashMap的底层实现:

  • jdk7中使用数组加链表
  • jdk8中使用数组加链表/红黑树(防止一个桶里的链表过于长,导致效率低下,加入了红黑树的存储方式)

主要思路:

1. 基本节点数据结构Node

HashMap中每一个节点使用的是Node类,包含了key、value、hash、next。

2. 数组大小问题

其数组默认大小是16,但是当用户初始化指定capacity时,(注意:capacity并非map的极限容量,只是决定你要把这个数组开多大,因此你put了多余capacity的元素也不会出现问题, 数组大小为大于等于capacity的最小2的整数幂。

3. 数组扩大问题

3.1 发生条件:
  1. 当size>thresHold,即node总数大于数组大小时就进行扩容。(node几乎不会各占一个位置,很大可能集中到几个数组元素中了)
  2. 当某条链表大小>8,但是数组大小还小于64;优先进行扩容而不是转化红黑树
3.2 扩容方式

capacity变为两倍(不超过最大限制2^30的话),对于每个元素进行rehash重新放入.

4. 链表转红黑树的条件

当一个数组的node对应的链表的大小超过TREEIFY_THRESHOLD(常量8)时,

  • 如果数组大小大于MIN_TREEIFY_CAPACITY(常量64),会转化为红黑树。
  • 如果数组大小没有超过64,优先进行resize()

5. 红黑树转链表的条件

主要根据树具体结构,官方注释是2~6个node的时候

Node

hashmap中每个节点是一个node,成员变量包括key,value,hash,next;并不是简单的键值对;Node类的一些方法:

  • toString(): key+“=”+value
  • hashCode():hashCode(key)^hashCode(value)
  • setValue(newValue):新value替换原value,返回原value
  • 键和值都相等.

hashMap中的成员变量:

  • Node<K,V> [] table:桶数组
  • size:map中键值对的数量
  • modCount:记录该map结构修改的次数,包括增加删除/改变结构/扩容等,
  • threshold:table array的大小(capacity*loadFactor)
  • loadFactor:table的负载因子
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值