当前位置: 首页 > news >正文

真的了解HashMap、HashSet吗?做一道测试题试试!

本人博客《HashMap、HashSet底层原理分析》,可以了解hashmap的底层源码实现

测试代码

HashSet底层实际就是一个Hashmap。猜猜下面源码每一个打印结果。
注:user对象重写的hashcode方法,保证name和age一样的情况下hashcode是一样的,

import java.util.*;public class HashmapTest {public static void main(String[] args) {HashMap map = new HashMap();User u1 = new User("AA");User u2 = new User("BB");map.put(u1,1);map.put(u2,2);System.out.println("结果一(put u1 u2  后)="+map);// u1 重新Set nameu1.setName("CC");System.out.println("结果二(u1 set name 后)="+map);// 移除 u1map.remove(u1);System.out.println("结果三(remove u1 后)="+map);// put user(CC)map.put(new User("CC"),3);System.out.println("结果四(put user(CC) 后)="+map);// put user(AA)map.put(new User("AA"),4);System.out.println("结果五(put user(AA) 后)="+map);}
}class User{private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public User(String name, int age) {this.name = name;this.age = age;}public User(String name) {this.name = name;}public User() {}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}

测试结果

结果一(put u1 u2  后)={User{name='BB', age=0}=2, User{name='AA', age=0}=1}
结果二(u1 set name 后)={User{name='BB', age=0}=2, User{name='CC', age=0}=1}
结果三(remove u1 后)={User{name='BB', age=0}=2, User{name='CC', age=0}=1}
结果四(put user(CC) 后)={User{name='BB', age=0}=2, User{name='CC', age=0}=3, User{name='CC', age=0}=1}
结果五(put user(AA) 后)={User{name='BB', age=0}=2, User{name='CC', age=0}=3, User{name='CC', age=0}=1, User{name='AA', age=0}=4}

分析

结果一和结果二属于Java基础

结果三分析

结论:并没有移除u1成功。

map.remove(u1);

1、了解put方法做了哪些事?
map.put(u1,1); 第一次put时,数组下标、Node节点中保存的hash均是通过new User(“AA”)计算并保存的
2、SetName后,该节点中保存了什么?
u1.setName(“CC”); SetName时,只改变了值,Node节点在数组中的位置、Node节点中保存的hash值均还是new User(“AA”)的
3、了解map是怎么实现remove?

  • remove和put是类似的,通过remove传入的对象,经过计算下标,然后和该下标内的数据进行比对(hash值相等 且 (== 或 equals))。

  • 原Node在数组中下标、Node内hash值均保存的是new User(“AA”),但是remove传入的却是CC,就算下标一样,hash值肯定是不一样的,所以并不会移除u1对象

结果四分析

结论:成功put。

map.put(new User("CC"),3);

1、通过结果三分析已经知道put时做了那些事,就算Hash计算的下标一样,hash值和目前存在的数据肯定是不一样的,所以是可以正常加入的。
2、假设计算后下标一致,u1 节点保存的hash值是AA的,结果四put的是CC的hash,所以肯定不一样,此时是可以正常加入的

结果五分析

结论:成功put。

map.put(new User("AA"),4);

1、通过结果三分析已经知道remove时做了那些事,实际put也一样,hash冲突(下标相等)时,hash值相等 且 (== 或 equals)时才会认为是相等的
2、此时put进去的new User(“AA”)和原保存进去的u1,两者hash冲突(因为user对象重新了hashcode方法,hashcode是一样的,计算后的下标是一样的),hash值也相等(都是AA的),但是u1实际保存的Name是CC,不论是==还是equals均返回的是false,所以也是可以正常put进去的

http://www.lryc.cn/news/14044.html

相关文章:

  • 树莓派下安装OpenEuler
  • VSCode Remote-SSH配置免密登录踩坑
  • 【Python语言基础】——Python NumPy 数组拆分
  • 虹科资讯| 虹科AR荣获汽车后市场“20佳”维修工具评委会提名奖!
  • Mysql架构与内部模块
  • 从技术上来看,互联网技术开始衍生和蜕变出更多的新技术
  • 最长不含重复字符的子字符串
  • git中git push origin master推送远程操作失败,报错解决方案
  • 服务器部署流程与经验记录
  • 超火的情感视频短视频账号,赚钱的路子有多野?
  • Linux系列 linux 常用命令(笔记)
  • Cosmos 基础教程(二)-- Run a Node, API, and CLI
  • C# 读写xml文件总结 [详细]
  • 【Java基础】IO流
  • Boolean,Array,Object数据类型(回顾)
  • Python常见的数据类型
  • 欠缺知识点罗列
  • 基于springboot+vue的校园社团管理系统(前后端分离)
  • 你了解互联网APP推荐的背后逻辑么(下)?
  • 总是跳转到国内版(cn.bing.com)?New Bing使用全攻略
  • 神经网络的基本骨架—nn.Module使用
  • 面试官:你是怎样进行react组件代码复用的
  • arxiv2017 | 用于分子神经网络建模的数据增强 SMILES Enumeration
  • 倒计时2天!TO B人的传统节日,2023年22客户节(22DAY)
  • java版工程管理系统Spring Cloud+Spring Boot+Mybatis实现工程管理系统源码
  • 数据结构刷题(六):142环形链表II、242有效的字母异位词、383赎金信、349两个数组的交集
  • OpenGL学习日记之光照计算
  • 七大排序经典排序算法
  • 设计模式—“对象性能”
  • 基于Spring Boot的零食商店