热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaHashtable涉及的数据结构、实现及冲突处理

为什么80%的码农都做不了架构师?Hashtable提供的功能Hashtable是一个线程安全的Map,其线程安全是通过在各个方法上加上synch

为什么80%的码农都做不了架构师?>>>   hot3.png

Hashtable 提供的功能
  • Hashtable是一个线程安全的Map,其线程安全是通过在各个方法上加上synchronized关键字实现的,即:该类只能被一个线程所使用,其他调用该类时会阻塞等待;
  • 实现了哈希表,映射key到value;
  • key和value都不能为null,key类型必须实现hashCode()和equals()方法;
  • put(K k,V v);
  • get(K k,V v);
  • Hashtable没有实现hash冲突的解决方案,冲突需要按自己的逻辑实现,它只提供了哈希表自动扩容的功能;
  • 出现hash冲突时,采用单向链表来储存冲突的元素。
Hashtable 涉及到的概念
  • 初始化容量:key数组初始长度,默认值是11
  • 负载系数&#xff08;load factor&#xff09;&#xff1a;即到达容量的百分比时&#xff0c;哈希表就会重新hash到一个新容量的哈希表中,取值范围是&#xff1a;<1.0 的百分数 默认取值是.75(75%&#xff0c;当加入的键值对数量达到初始容量的75%时&#xff0c;继续加入的话会重新hash到一个新的容量的哈希表中)
  • 阈(yù)值&#xff1a;threshold&#61;初始化容量*0.75和Integer.MAX_VALUE-8&#xff08;注&#xff1a;Integer.MAX_VALUE&#61;0x7FFFFFFF&#xff09; 中较小值
  • 重新Hash&#xff1a;加入元素时&#xff0c;当数组大小大于等于阈值时&#xff0c;key数组的容量会左移2位后&#43;1即&#xff1a;原容量*4&#43;1&#xff0c;然后按新的容量hash后放入新的数组中。
  • 哈希函数&#xff1a;(key.hashCode() & 0x7FFFFFFF) % key数组现在的长度
Hashtable常用方法分析
  • put(K k,V v); 添加元素到哈希表时&#xff0c;判断元素是否存在&#xff0c;如果存在&#xff08;key的hash相同并且值也相同&#xff09;的话&#xff0c;就会覆盖掉原来的元素&#xff0c;并返回原来的值&#xff1b;如果不存在的话&#xff0c;就会直接新建一个元素&#xff0c;若产生hash冲突则将旧元素链接到新元素的尾部。
  • get(K k); 获取元素时&#xff0c;先根据key的hash获取到对应key数组的下标&#xff0c;获取对应的元素&#xff08;因为数组元素的值是一个单链表&#xff0c;所以如果当前的值不匹配时就需要判断链表的下一个元素&#xff09;。
处理 Hash冲突

Hashtable 处理 Hash冲突 时通过单链表。。

涉及的基本概念
  • 位运算
  • 数组
  • 哈希表
  • 单链表
  • Java transient 关键字原理
  • Java 序列化、反序列化以及自定义序列化、反序列话逻辑&#xff08;writeObject(ObjectOutputStream o)和readObject(ObjectInputStream i)&#xff09;
存在未理解之处

Hashtable的count字段是什么时候初始化的&#xff1f;从赋值来看是通过readObject()方法来实现的。但是具体实现需要回去取研读下《Java编程思想》序列化章节内容。

private transient int count;
未理解之处的解答

  • Hashtable的count字段是什么时候初始化的&#xff1f;因为该变量是类变量编译的时候会自动赋值。可以总结下Java各种类型的变量。
模拟hash冲突

可以根据hash函数(key.hashCode() & 0x7FFFFFFF) % key数组现在的长度来模拟hash冲突&#xff0c;只要key的hashCode是相同但是又不equals()的就是Hash冲突。如下实例&#xff1a;

public class MyKey implements Serializable {private int i;public MyKey(int i) {this.i &#61; i;}[&#64;Override](https://my.oschina.net/u/1162528)public int hashCode() {if (i % 2 &#61;&#61; 0) {return 1;} else {return 2;}}}
Hashtable处理hash冲突

如下实例&#xff1a;

public static void main(String[] args) {Hashtable map &#61; new Hashtable<>();for (int i &#61; 0; i <11; i&#43;&#43;) {map.put(new MyKey(i), i);}map.get(new MyKey(1));
}
如何在IDEA调试模式下查看储存结构&#xff1f;

Hashtable在IDEA下的默认视图&#xff1a;

Java-Hashtable-data-structure-default-view

如何查看对象视图&#xff1f;如下图操作&#xff1a;

Java-Hashtable-data-structure

对象视图如下

Java-Hashtable-data-structure-object-view

从如上对象视图可以看出Hashtable的table字段的具体存储方式&#xff1a; table数组中有两个元素&#xff0c;一个是MyKey.i&#61;10&#xff0c;一个是Mykey.i&#61;9,按如上查看对象视图的方法查看这两个元素的对象视图查看java.util.Hashtable.Entry#next属性&#xff0c;可以看到MyKey.i&#61;10的next属性值是MyKey.i&#61;8... 各元素的具体结构如下&#xff1a;

MyKey.i&#61;10.next -> MyKey.i&#61;8
MyKey.i&#61;8.next -> MyKey.i&#61;0
MyKey.i&#61;0.next -> MyKey.i&#61;2
MyKey.i&#61;2.next -> MyKey.i&#61;4
MyKey.i&#61;4.next -> MyKey.i&#61;6
MyKey.i&#61;6.next -> nullMyKey.i&#61;9.next -> MyKey.i&#61;1
MyKey.i&#61;1.next -> MyKey.i&#61;3
MyKey.i&#61;3.next -> MyKey.i&#61;5
MyKey.i&#61;5.next -> MyKey.i&#61;7
MyKey.i&#61;7.next -> null

为什么顺序不是按加入的顺序的呢&#xff0c;而是一部分到过来的&#xff1f;
因为Hashtable的key数组默认大小是11&#xff0c;当加入11个元素时&#xff0c;会自动扩容&#xff0c;在加入第8个元素时会rehash一次&#xff0c;rehash时是将新哈希表中的元素作为后面加入元素的next的&#xff0c;所有就会出现部分元素顺序相反。


转:https://my.oschina.net/jast90/blog/2962386



推荐阅读
  • java datarow_DataSet  DataTable DataRow 深入浅出
    本篇文章适合有一定的基础的人去查看,最好学习过一定net编程基础在来查看此文章。1.概念DataSet是ADO.NET的中心概念。可以把DataSet当成内存中的数据 ... [详细]
  • Hadoop MapReduce 实战案例:手机流量使用统计分析
    本文通过一个具体的Hadoop MapReduce案例,详细介绍了如何利用MapReduce框架来统计和分析手机用户的流量使用情况,包括上行和下行流量的计算以及总流量的汇总。 ... [详细]
  • 深入理解Java字节码:方法调用详解
    本文详细介绍了Java字节码中的方法调用机制,通过具体示例解析了字节码如何处理方法调用及其参数传递。文章由Mahmoud Anouti撰写,原文链接:https://dzone.com/articles/introduction-to-java-bytecode ... [详细]
  • 本文介绍了如何使用Java编程语言实现凯撒密码的加密与解密功能。凯撒密码是一种替换式密码,通过将字母表中的每个字母向前或向后移动固定数量的位置来实现加密。 ... [详细]
  • 本文介绍如何通过Java代码调用阿里云短信服务API来实现短信验证码的发送功能,包括必要的依赖添加和关键代码示例。 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • JavaSE 基础语法详解
    本文详细介绍了JavaSE的基础语法,涵盖数据类型、变量与常量、流程控制语句及数组等内容,旨在为初学者提供全面的学习指南。 ... [详细]
  • 本文档旨在提供C语言的基础知识概述,涵盖常量、变量、数据类型、控制结构及函数定义等内容。特别强调了常量的不同类型及其在程序中的应用,以及如何正确声明和使用函数。 ... [详细]
  • 来自FallDream的博客,未经允许,请勿转载,谢谢。一天一套noi简直了.昨天勉强做完了noi2011今天教练又丢出来一套noi ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 题面:P3178[HAOI2015]树上操作好像其他人都嫌这道题太容易了懒得讲,好吧那我讲。题解:第一个操作和第二个操作本质上是一样的&# ... [详细]
  • HDU 2537 键盘输入处理
    题目描述了一个名叫Pirates的男孩想要开发一款键盘输入软件,遇到了大小写字母判断的问题。本文提供了该问题的解决方案及实现方法。 ... [详细]
  • Java高级工程师学习路径及面试准备指南
    本文基于一位朋友的PDF面试经验整理,涵盖了Java高级工程师所需掌握的核心知识点,包括数据结构与算法、计算机网络、数据库、操作系统等多个方面,并提供了详细的参考资料和学习建议。 ... [详细]
  • 本文详细探讨了select和epoll两种I/O多路复用技术的内部实现原理,分析了它们在处理大量文件描述符时的性能差异,并通过具体示例代码展示了select的工作流程。 ... [详细]
  • 本文介绍了如何通过安装和配置php_uploadprogress扩展来实现文件上传时的进度条显示功能。通过一个简单的示例,详细解释了从安装扩展到编写具体代码的全过程。 ... [详细]
author-avatar
_戒咗微博地_100
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有