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. javascript之构造函数的继承(引用网络)

    这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有一个" ...

  2. Illumina Sequence Identifiers 序列标识符 index详解

    大家基本都知道什么是 FASTA 和 FastQ 格式了,但这是不够的. 我们还需要了解世界上最大的测序公司自己定制的 FastQ 格式,因为你可能会经常用到,有时还会亲自去处理它们. 本文主题:Il ...

  3. 013 - 关于GC root: Native Stack | MAT分析

      Question:   I have some third library code that I run and after some time I run into OutOfMemoryEr ...

  4. memcached客户端连接建立过程笔记

    memcached在启动过程初始化server_sockets时,根据启动参数决定系统是进行tcp监听还是udp监听,这里暂时只关注tcp的情况. server_socket在初始化时会向系统申请监听 ...

  5. android-------高德地图两点路线和多个点路线绘制

    最近朋友需要两点路线和多个点路线绘制这个功能,帮忙弄了一下,写这篇博客与大家分享一下. 两点路线 是起点和终点两个经纬度点,高德绘制出路线,可以实现实线和虚线功能 效果图:    相关属性: mPol ...

  6. laravel 懒加载

    故事背景是什么呢? 目录大家都知道吧,一般有几个层级,根据公司需求,要将目录以树的形式展示出来,为了提高访问速度,这些目录数据要一次性读取出来的.这样的话就涉及到了查询,优化查询次数是一个很关键的事情 ...

  7. Python基础--列表、元组

    一.什么是列表.元组 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置类型,但最常见 ...

  8. POJ-1180 Batch Scheduling (分组求最优值+斜率优化)

    题目大意:有n个任务,已知做每件任务所需的时间,并且每件任务都对应一个系数fi.现在,要将这n个任务分成若干个连续的组,每分成一个组的代价是完成这组任务所需的总时间加上一个常数S后再乘以这个区间的系数 ...

  9. Java IO流中的flush()

    通过BufferedOutputStream或BufferedWriter 链接到底层流上来实现.因此,在写 完数据时,flush就显得尤为重要. 例如: 上图中WEB服务器通过输出流向客户端响应了一 ...

  10. 使用路径arc

    <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>    < ...