package tt;

import java.util.HashMap;
import java.util.Map; public class a0 {
public static void main(String[] args){ /**
* 如果两个对象相同,那么这两个对象的hashCode一定要相同
String a1 ="abc"   String a2 ="abc" 这a1和a2就是相同的对象
*
* 两个对象的hashCode相同,并不一定表示两个对象就相同,他们“存放在同一个篮子里”
      String s1 = new String("abc") String s2 = new String("abc")
*
* 验证:只要2个对象的内容是同的返回hashCode是相同的
* 那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
*/
Integer i1 = 100; Integer i2=Integer.valueOf(100);
String s1="a"; String s2="a";
//实质会执行如下的代码 Integer i1 = Integer.valueOf(100),上面的2句话是等效的
//若int值在[-128,-127]之间的话,会返回缓冲池的数据,否的 return new Integer(i)
System.out.println(i1==i2);//true
System.out.println(s1==s2);//true
System.out.println("code"+i1.hashCode()+","+i2.hashCode()+";"+s1.hashCode()+","+s2.hashCode());
//code100,100;97,97
//Integer 变量名; 若值在[-128,-127]之间,变量名都是指向同一对象
//String str="abc" 只要后面的值都相同,多个变量名指向同一个“abc” Integer i3 = new Integer(100); String ss = new String("a");
System.out.println(i1==i3);//flase
System.out.println(s2== ss);//false
System.out.println("code"+i1.hashCode()+","+i3.hashCode()+";"+s2.hashCode()+","+ss.hashCode());
//code100,100;97,97 Integer in = new Integer(100);
Integer in1 = new Integer(100);
String abc = "abcd";
String abc1="abcd";
System.out.println("code"+in.hashCode()+","+in1.hashCode()+";"+abc.hashCode()+","+abc1.hashCode());
//code100,100;2987074,2987074
//对象肯定不同的,但是内容是同的 String str1 = "name"; String str2 = new String("name");
System.out.println(str1==str2);//false
System.out.println(str1.hashCode() +" "+ str2.hashCode());//3373707 3373707
Map<String,String> map =new HashMap<String,String>();
/* 如果key在链表中已存在,则替换为新value*/
* 对象equals 是true的话,hashCode需要相同,但是hashCode相同的对象不一定equals,这就是所谓的冲突现象,但是有不同的冲突解决方法。你的hashCode()设计的好的话冲突也就小了。比如楼上给出的超出int范围之后这种hashCode()实现,对象肯定是无数的,但是hash实现是有限的呢,所以冲突了
*/ map.put(str1,"Tom");
map.put(str2, "Lisa");
System.out.println(map); //输出 name = "Lisa" //你构造不出 key1 和 key2 对象不同,但是他们的hashcode相同
}
}

HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

Put操作:

如果两个key通过hash%Entry[].length得到的index相同,会不会有覆盖的危险?

  这里HashMap里面用到链式数据结构的一个概念。上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。打个比方, 第一个键值对A进来,通过计算其key的hash得到的index=0,记做:Entry[0] = A。一会后又进来一个键值对B,通过计算其index也等于0,现在怎么办?HashMap会这样做:B.next = A,Entry[0] = B,如果又进来C,index也等于0,那么C.next = B,Entry[0] = C;这样我们发现index=0的地方其实存取了A,B,C三个键值对,他们通过next这个属性链接在一起

当我们往HashMap中put元素的时候,先根据key的重新计算元素的hashCode,根据hashCode得到这个元素在table数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上

get操作(先hashcode方法再equals方法)

有了上面存储时的hash算法作为基础,理解起来这段代码就很容易了。从上面的源代码中可以看出:从HashMap中get元素时,首先计算key的hashCode,找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到需要的元素。

(考研)散列表和hashcode和hashmap的更多相关文章

  1. 散列表(拉链法与线性探测法)Java实现

    package practice; import java.security.Principal; import java.util.Scanner; import edu.princeton.cs. ...

  2. 实现一个简单的散列表(HashMap)

    下面参考java.util.HashMap<K, V>,写了一个简单的散列表,只实现了其中的put和get方法,使用链接法"碰撞冲突".代码最后,自定义了一个Peopl ...

  3. HashMap、lru、散列表

    HashMap HashMap的数据结构:HashMap实际上是一个数组和链表("链表散列")的数据结构.底层就是一个数组结构,数组中的每一项又是一个链表. hashCode是一个 ...

  4. Java HashMap源码分析(含散列表、红黑树、扰动函数等重点问题分析)

    写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...

  5. 哈希表查找(散列表查找) c++实现HashMap

    算法思想: 哈希表 什么是哈希表 在前面讨论的各种结构(线性表.树等)中,记录在结构中的相对位置是随机的,和记录的关键字之间不存在确定的关系,因此,在结构中查找记录时需进行一系列和关键字的比较.这一类 ...

  6. 散列表(hash table)——算法导论(13)

    1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...

  7. Java学习笔记(二十)——Java 散列表_算法内容

    [前面的话] 周末,本来打算找人去玩,结果没找到,所以我只好有学习了. 为什么会学习散列表,因为要使用HashMap?因为在做项目的时候,在服务器和客户端需要传输DTO,而传输的属性是动态增加的,所以 ...

  8. 深入解析Java对象的hashCode和hashCode在HashMap的底层数据结构的应用

    转自:http://kakajw.iteye.com/blog/935226 一.java对象的比较 等号(==): 对比对象实例的内存地址(也即对象实例的ID),来判断是否是同一对象实例:又可以说是 ...

  9. Java 集合 散列表hash table

    Java 集合 散列表hash table @author ixenos 摘要:hash table用链表数组实现.解决散列表的冲突:开放地址法 和 链地址法(冲突链表方式) hash table 是 ...

随机推荐

  1. LINQ 系列

    C#图解教程 第十九章 LINQ   LINQ 什么是LINQLINQ提供程序 匿名类型 方法语法和查询语法查询变量查询表达式的结构 from子句join子句什么是联结查询主体中的from…let…w ...

  2. 4-6 select_tag和select的区别和理解。javascript_tag

    via: :all是什么意思?主要用于约束http动作. <%= select_tag "set_locale", options_for_select(LANGUAGES, ...

  3. 1月28日周日,更新ruby到2.5.0版,rvm更新。

    在学习Array的方法的时候,发现文档concat方法可以进行多个数组的添加,而我的不行,猜测是ruby版本没有更新. 查询2.31ruby版本的concat方法,果然和2.5版本的不一样. 于是准备 ...

  4. 『Sklearn』框架自带数据集接口

    自带数据集类型如下: # 自带小型数据集# sklearn.datasets.load_<name># 在线下载数据集# sklearn.datasets.fetch_<name&g ...

  5. scrapy微信爬虫使用总结

    scrapy+selenium+Chrome+微信公众号爬虫 概述 1.微信公众号爬虫思路: 参考:记一次微信公众号爬虫的经历 2.scrapy框架图 3.scrapy经典教程 参考: python ...

  6. elasticsearch 路由文档到分片

    路由文档到分片 当你索引一个文档,它被存储在单独一个主分片上.Elasticsearch是如何知道文档属于哪个分片的呢?当你创建一个新文档,它是如何知道是应该存储在分片1还是分片2上的呢? 进程不能是 ...

  7. vue打包后图片找不到情况

    打包之前需要修改如下配置文件: 配置文件一:build>>>utils.js (修改publicPath:"../../" , 这样写是处理打包后找不到静态文件( ...

  8. jenkins安装笔记(一)

    转载地址:https://www.cnblogs.com/sylvia-liu/p/4485311.html 自动化架构搭建过程中为实现当开发源码更新时自动化脚本同步触发自动执行,使用到持续集成工具J ...

  9. kill prefix hemi hexa hepta holo input 1

    1● hemi 0.5 2● hexa 6 3● hepta 7 4● holo 100%

  10. Python Oracle数据库监控

    有的时候无法使用Oracle自带的OEM监控,那么就需要确定一个监控方案. 此方案,使用Python+Prometheus+Grafana+Oracle 1.监控配置表 -- Create table ...