HashMap实现保存两个key相同的数据


Posted in Java/Android onJune 30, 2021

HashMap如何保存两个key相同的数据

最近一个朋友去面试了,面试官问了一个关于HashMap的问题:HashMap如何保存两个key相同的数据?

准确来说,应该是Map中如何保存两个key相同的数据,因为用来实现这个功能的IdentityHashMap类和HashMap虽然都是实现了Map接口,但本质是属于不同的东西;

我们知道在HashMap中,如果key相同就会被覆盖,那IdentityHashMap是怎么实现这个功能的呢?

java jdk源码中,IdentityHashMap类上写了100来行注释的代码,如果用一句话来总结的话:

IdentityhashMap类利用哈希表实现Map接口,比较键(和值)时使用引用相等性代替对象相等性,也就是说key(value)比较的时候只比较两个key是否引用同一个对象,比较的是对象的地址;

测试1:

public static void main(String[] args) {
    String str1 = "key";
    String str2 = "key";
    System.out.println(str1==str2);
    Map<String, String> map = new IdentityHashMap<>();
    map.put(str1, "value1");
    map.put(str2, "value2");
    map.forEach((k,v)-> System.out.println(k+"->"+v));
}

打印:

true

key->value2

测试1中,将字符串"key"直接赋值给str1和str2,因为字符串是放在常量池中的,所以str1和str2实际上还是同一个对象,所以它们的key值是相同的,会被覆盖;

测试2:

public static void main(String[] args) {
    String str1 = new String("key");
    String str2 = new String("key");
    System.out.println(str1==str2);
    Map<String, String> map = new IdentityHashMap<>();
    map.put(str1, "value1");
    map.put(str2, "value2");
    map.forEach((k,v)-> System.out.println(k+"->"+v));
}

打印:

false

key value1

key value2

测试2中,str1和str2是通过new的方式创建出来的,属于不同对象,所以它们的引用不同,key值也就不同,所以put的时候不会被覆盖;

关于IdentityHashMap常不常用,实际开发中我基本没用过,所以在什么场景会用到IdentityHashMap我也说不出个一二来;不过存在即合理,肯定有什么场景会用到的,后面遇到我会及时更新~

HashMap插入相同key

使用HashMap在插入操作时,会通过equal方法判断key是否相同。如果相同,则将覆盖对应的value;不相同才使用新的“桶”。

我的问题

当往HashMap中插入数据,即使有相同的key,但是能不能不进行覆盖操作,而是把新的value放在原有的value附近能够找到的位置?

想法

呃,其实大概方向就是通过一个HashMap<Integer, ArrayList>实现。。。

贴上代码

import java.util.ArrayList;
import java.util.HashMap; 
public class MapAndLink { 
    public static void main(String[] args){ 
        HashMap<Integer, ArrayList> map = new HashMap<>();
        put(1, 1, map);
        put(1, 3, map);
        put(2, 2, map);
        put(3, 4, map);
        put(1, 3, map);
        System.out.println(map.toString());
    }
 
    public static void put(Integer key, Integer str, HashMap<Integer, ArrayList> map){
        ArrayList<Integer> list = map.get(key);
        if(list == null)
            list = new ArrayList();
        for(int i = 0; i < list.size(); ++i){
            if(list.get(i).equals(str))
                return;
        }
        list.add(str);
        map.put(key, list);
    }
}

再贴上输出结果

{1=[1, 3], 2=[2], 3=[4]}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Java/Android 相关文章推荐
SpringCloud Alibaba 基本开发框架搭建过程
Jun 13 Java/Android
Java常用工具类汇总 附示例代码
Jun 26 Java/Android
探讨Java中的深浅拷贝问题
Jun 26 Java/Android
dubbo集成zipkin获取Traceid的实现
Jul 26 Java/Android
Java比较两个对象中全部属性值是否相等的方法
Aug 07 Java/Android
Java面试题冲刺第十九天--数据库(4)
Aug 07 Java/Android
springboot+zookeeper实现分布式锁
Mar 21 Java/Android
Java基础——Map集合
Apr 01 Java/Android
JAVA长虹键法之建造者Builder模式实现
Apr 10 Java/Android
springboot读取resources下文件的方式详解
Jun 21 Java/Android
Java代码规范与质量检测插件SonarLint的使用
Aug 05 Java/Android
Java实现贪吃蛇游戏的示例代码
Sep 23 Java/Android
spring boot项目application.properties文件存放及使用介绍
springboot项目以jar包运行的操作方法
Springboot使用Spring Data JPA实现数据库操作
Jun 30 #Java/Android
如何给HttpServletRequest增加消息头
解决ObjectMapper.convertValue() 遇到的一些问题
Jun 30 #Java/Android
Java基础之详解HashSet的使用方法
Java实现多文件上传功能
Jun 30 #Java/Android
You might like
PHP5在Apache下的两种模式的安装
2006/09/05 PHP
基于PHP生成静态页的实现方法
2013/05/10 PHP
PHP CodeBase:将时间显示为&quot;刚刚&quot;&quot;n分钟/小时前&quot;的方法详解
2013/06/06 PHP
PHP批量查询WordPress留言者E-mail地址实现方法
2015/02/15 PHP
PHP创建自己的Composer包方法
2018/04/09 PHP
php输出形式实例整理
2020/05/05 PHP
Centos7.7 64位利用本地完整安装包安装lnmp/lamp套件教程
2021/03/09 Servers
TFDN图片播放器 不错自动播放
2006/10/03 Javascript
Javascript面象对象成员、共享成员变量实验
2010/11/19 Javascript
容易被忽略的JS脚本特性
2011/09/13 Javascript
javascript 弹出的窗口返回值给父窗口具体实现
2013/11/23 Javascript
JavaScript按位运算符的应用简析
2014/02/04 Javascript
基于jQuery实现下拉框
2014/11/24 Javascript
JS实现自动切换文字的导航效果代码
2015/08/27 Javascript
使用jQuery实现Web页面换肤功能的要点解析
2016/05/12 Javascript
React创建组件的三种方式及其区别
2017/01/12 Javascript
SVG描边动画
2017/02/23 Javascript
微信小程序scroll-view实现横向滚动和上拉加载示例
2017/03/06 Javascript
微信小程序 空白页重定向解决办法
2017/06/27 Javascript
vue中v-model动态生成的实例详解
2017/10/27 Javascript
写一个移动端惯性滑动&amp;回弹Vue导航栏组件 ly-tab
2018/03/06 Javascript
浅谈vue中.vue文件解析流程
2018/04/24 Javascript
ES6 迭代器与可迭代对象的实现
2019/02/11 Javascript
怎样使你的 JavaScript 代码简单易读(推荐)
2019/04/16 Javascript
微信小程序云开发之使用云函数
2019/05/17 Javascript
微信小程序中网络请求缓存的解决方法
2019/12/29 Javascript
[02:31]DOTA2帕克 英雄基础教程
2013/11/26 DOTA
[58:09]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第三场 6.2
2018/06/03 DOTA
pytorch在fintune时将sequential中的层输出方法,以vgg为例
2019/08/20 Python
TensorFlow tf.nn.softmax_cross_entropy_with_logits的用法
2020/04/19 Python
html5的新增的标签和废除的标签简要概述
2013/02/20 HTML / CSS
前台领班岗位职责
2013/12/04 职场文书
毕业生求职信范文
2014/06/29 职场文书
基层党支部整改方案
2014/10/25 职场文书
会计专业自荐信范文
2019/05/22 职场文书
javascript函数式编程基础
2021/09/15 Javascript