HashMap用String作为key出现重复

背景:读入文件数据,使用hashMap嵌套存储,出现key重复

问题如下:
在这里插入图片描述
文件格式使用csv格式,逗号分隔
数据如下:
在这里插入图片描述
源码如下:

package fileToData;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
/**
 * Created by wang on 2019/01/11.
 */
public class readFile {
    private String filepath = "C:\\Users\\wang\\Desktop\\ceshi.csv";
    private String division = ",";
    private Map<String, Map<String, Integer>> uMap;
    
    public readFile() {
        uMap = new LinkedHashMap<>();
    }

    public void initMaps() throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader(filepath));
        String line;
        while ((line = reader.readLine()) != null) {
            String[] split = line.split(division);
            //添加数据
            if (!uMap.containsKey(split[0])) {
                Map<String, Integer> tempMap = new LinkedHashMap<>();
                tempMap.put(split[1], Integer.parseInt(split[3]));
                uMap.put(split[0], tempMap);
            } else {
                //添加重复key数据
                if (!uMap.get(split[0]).containsKey(split[1])) {
                    uMap.get(split[0]).put(split[1], Integer.parseInt(split[3]));
                }
            }
        }
        //关闭文件流
        reader.close();
    }
}

问题分析:

经过debug追踪查看发现两个字符串"1"的hash值不一样
在这里插入图片描述
在这里插入图片描述
如果key相同,但是hashcode不同,那么key不会被覆盖

如果key相同,但是hashcode相同,那么key会被覆盖

为什么会多了个字符"\uFEFF" ,hash值为65279呢?

可能问题出现在文件中,导致文件头有特殊字符,但我明明就是用的.csv格式

经过排查发现存在两种格式的csv:
问题是因为 使用了上面utf-8的那个格式,正确的是下面那个
问题是因为使用了上面utf-8的那个格式,正确的是下面那个

结论如下:
原因就是在文件头中的BOM标记造成,虽然文件内容看上去是正常的。
解决方法就是用文本编辑器将该文件重新另存为“无BOM标记”的文件即可。

以下是摘自网友的优秀回答:

理解hashmap在put和get时候的原理,这个问题也就比较简单了。先说put,hashmap会对key值做hashcode的操作,这个算出来的值也就是为了找到value存放的位置,如果这个位置上已经有元素,则以链表的方式添加在链表的尾部,如果没有元素,则放在该位置上。再说get,hashmap会根据get函数中传入的key,用hashcode找到元素的位置,如果该位置有一个元素则直接返回,如果多个元素,根据equals方法判断该位置链表中的元素是否为我要找的元素。那么回到本问题,对于标红出现的原因,第一次put的时候,根据"1"作为key算出来的hash值和第二次put"1"的时候算出来的hash值是不一样的

这个问题涉及HashMap存储key-value的原理。其实看源码,一切了然。我曾经看过源码,HashMap内部其实维护着一个链表数组。数组中的每个元素(即每条链表)维护着key-value链。当一对key-value被put进来的时候,先得到key的hashcode,然后以某种算法通过hashcode得到这对key-value应该被放到数组的哪个位置上。也就是说key-value放到数组的哪个位置取决于hashcode。而题主,虽然前后两次put进的key是同一个Person,但是age变了,hashcode也就变了。因此被放到了数组的不同位置上,最终导致key重复。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值