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. 2017-03-03 Oracle在.Net中出现未在本地计算机上注册“OraOLEDB.Oracle”提供程序的错误

    在前面的Oracle配置完成后,打开项目运行出错,出现未在本地计算机上注册“OraOLEDB.Oracle”提供程序的错误,看到“注册”两个字,首先想到,难道还要用命令行注册一下?果不其然,需要手动注 ...

  2. (转)HapMap简介

    1.人类基因组的HapMap和国际HapMap计划 (1)何谓HapMap HapMap是Haplotype Map 的简称,Haplo意为单一,在基因组中专指来自父母的一对染色体中的一条.Haplo ...

  3. OnXXX函数与XXX事件的关系

    OnPaint是Control类中的方法,Paint是事件,Paint是用于改变部分显示用比较合适,实际上Paint事件在OnPaint中被调用,如果你重写OnPaint但是不调用base.OnPai ...

  4. 基础最短路(模板 spfa)

    Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历,还 ...

  5. C#XML注释

    注释 <c>                             将说明中的文本标记为代码 <code>                       提供了一种将多行指示为 ...

  6. PHP:第四章——PHP数组array_diff计算数组差集

    <pre> <?php header("Content-Type:text/html;charset=utf-8"); /*知识点一:array_diff — 计 ...

  7. PHP:第一章——php中的变量001 /普通赋值/引用赋值/php变量的检查与销毁

    <?php //php中的变量: //php中的变量用一个美元符$后面紧跟着变量名来表示,变量名是区分大小写的. //有效的变量只能是字母或者下划线开头,后面跟任意数量的字母.数字.或者下划线. ...

  8. Flask初级(七)flash模板循环,判断

    Project name :Flask_Plan templates:templates static:static 继续前面的代码 修改Flask_Plan.py @app.route('/') d ...

  9. Log4j在Java工程中使用方法

    Eclipse新建Java工程,工程目录如下 1.下载log4j的Jar包,在Java工程下新建lib文件夹,将jar包拷贝到此文件夹,并将其加入到路径中,即:Jar包上右键——Build Path— ...

  10. C++内置类型的机器实现

    大多数计算机以2的整数次幂个比特作为块来处理内存,可寻址的最小内存块称为“字节(byte)”,存储的基本单元称为“字(word)”,它通常有几个字节组成. 计算机以比特序列存储数据,即01000101 ...