Hashtable是Java中键值对数据结构的实现。您可以使用“键”存储和检索“值”,它是存储值的标识符。显然“关键”应该是独一无二的。

java.util.Hashtable扩展Dictionary并实现Map。具有非空值的对象可以用作键或值。Hashtable的密钥必须实现hashcode()和equals()方法。在这篇文章的最后,你会发现这个条件背后的原因。

通常,使用空构造函数 Hashtable()创建Java中的Hashtable。这是一个糟糕的决定,而且经常重复的错误。Hashtable有两个其他构造函数

Hashtable(int initialCapacity)(int initialCapacity )

Hashtable(int initialCapacity,float loadFactor)(int initialCapacity ,float loadFactor )

。初始容量是在Hashtable实例化时创建的桶数。桶的逻辑空间存储的哈希表。

哈希和哈希表

在查看java的Hashtable之前,你应该明白一般的哈希。假设v是要存储的值,k是用于存储/检索的密钥,则h是在表的h(k)处存储v的哈希函数。要获取值计算h(k),以便您可以直接获取v的位置。因此,在键值对表中,您不需要顺序扫描键以识别值。

h(k)是散列函数,它用于找到存储对应值的位置v。h(k)不能计算到不确定空间。分配给Hashtable的存储在程序中受到限制。因此,散列函数h(k)应该返回该分配频谱(逻辑地址空间)内的一个数字。

在Java中进行散列

Java的散列使用从键和值对象使用hashCode()方法进行计算。以下是来自Hashtable的核心代码,其中计算了hashCode'h'。你可以看到key和value的hashCode()方法被调用。

h += e.key.hashCode() ^ e.value.hashCode();
+= e.key.hashCode() ^ e.value.hashCode();
 

最好在您的自定义对象中使用hashCode()方法。String具有自己的hashCode方法,它计算hashcode值如下:

 
s[0]*31^(n-1)
+ s[1]*31^(n-2)
+ ...
+ s[n-1][0]*31^(n-1) + s[1]*31^(n-2)
  + ...
+ s[n-1]
 

如果没有hashCode()方法,那么它是从Object类派生的。以下是来自Object类的hashCode()方法的javadoc注释

返回对象的哈希码值。支持这种方法是为了哈希表的好处,如java.util.Hashtable提供的那些。

如果要编写一个自定义的hashCode(),那么请遵循以下合同:

hashCode的一般契约是:无论何时在执行Java应用程序时多次在同一对象上调用该对象,hashCode方法必须始终返回相同的整数,前提是在对象上的equals比较中没有使用任何信息被修改。

以下是提高Hashtable的性能。

如果两个对象根据equals(Object)方法相等,那么在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。

hashCode()通过使用对象的内部地址来保证不同的整数。

碰撞在Hashtable

当我们尝试在分配的地址范围限制范围内限制散列函数的输出时,有可能发生冲突。对于两个不同的键k1和k2,如果我们有h(k1)= h(k2),那么这就是哈希表中的碰撞。这是什么意思,我们的散列函数指示我们在同一位置存储两个不同的值(键也不同)。

当碰撞时,有多种方法可以解决它。命名几个哈希表冲突解决技术,“单独链接”,“开放寻址”,“罗宾盖哈希”,“布谷鸟哈希”等。Java的哈希表使用“分离链接”来在Hashtable中进行冲突解决。

在Java的Hashtable中的碰撞解决方案

Java使用单独的链接进行冲突解决。回想一下,Hashtable将元素存储在存储桶中。在单独链接中,每个桶将存储对链表的引用。现在假设你已经存储了一个元素在桶1中。这意味着,在第1桶中,您将有一个链表的引用,在该链表中,您将有两个单元格。在这两个单元格中,您将具有键及其相应的值。

为什么要存储密钥?因为当有冲突时,即当两个键产生相同的哈希码并指向相同的存储桶(假设存储桶1)时,您也要将第二个元素存储在同一个存储桶中。将此第二个元素添加到已创建的链接列表作为相邻元素。

现在,当您检索到一个值时,它将计算哈希码并将其引导到具有两个元素的存储桶。您可以顺序扫描这两个元素,并使用它们的equals()方法比较键。当关键数学你得到相应的值。希望你有理由背后的条件,你的对象必须有hashCode()和equals()方法。

Java在Hashtable中有一个私有静态类Entry。它是一个列表的实现,你可以看到,它存储的关键和价值。

哈希表演

要从您的Java Hashtable获得更好的性能,您需要
使用initialCapacity和loadFactor参数
2)
在实例化Hashtable时明智地使用它们。

initialCapacitiy是在Hashtable实例化时创建的桶数。桶的数量和碰撞的概率是相反的。如果您需要更多的桶数,则碰撞的可能性较小。

例如,如果要存储10个元素,并且如果要将initialCapacity设置为100,那么您将拥有100个桶。您将计算hashCoe()只有10次,频谱为100个桶。碰撞的可能性非常少。

但是,如果要将Hashtable的initialCapacity提供为10,则碰撞的可能性非常大。loadFactor决定何时自动增加Hashtable的大小。initialCapacity的默认大小为11,loadFactor为.75如果Hashtable的大小为3/4,则Hashtable的大小将增加。

Java Hashtable中的新容量计算如下:

	int newCapacity = oldCapacity * 2 + 1;int newCapacity = oldCapacity * 2 + 1 ;

如果您提供较小的容量和加载因子,并且通常会执行rehash(),这会导致性能问题。因此,为了在Java中实现Hashtable的高效性能,在实例化时,将initialCapacity作为您需要的25%,loadFactor为0.75。

Java之 Hashtable的更多相关文章

  1. java.util.HashMap和java.util.HashTable (JDK1.8)

    一.java.util.HashMap 1.1 java.util.HashMap 综述 java.util.HashMap继承结构如下图 HashMap是非线程安全的,key和value都支持nul ...

  2. Java:Hashtable

    概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习.我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable.第1部分 Ha ...

  3. Java的Hashtable类(转)

    文章来源:http://blog.csdn.net/zhna123_2011/article/details/6741479 ps:直接copy 哈希表是一种重要的存储方式,也是一种常见的检索方法.其 ...

  4. JAVA的Hashtable在遍历时的迭代器线程问题

    这篇博客主要讲什么 Hashtable及其内部类的部分源码分析 Hashtable在遍历时的java.util.ConcurrentModificationException异常的来由和解决 单机在内 ...

  5. Java 之 Hashtable 集合

    Hashtable 集合  java.util.Hashtable<K,V>集合 implements Map<K,V>接口  Hashtable:底层也是一个哈希表,是一个线 ...

  6. java.util.HashTable (JDK1.8)

    1.Hashtable 特性(先总结下面会详细讲的): 1.Hashtable 存储的内容是键值对(key-value)映射,其底层实现是一个Entry数组+链表. 2.Hashtable是线程安全( ...

  7. Java:HashTable类小记

    Java:HashTable类小记 对 Java 中的 HashTable类,做一个微不足道的小小小小记 概述 public class Hashtable<K,V> extends Di ...

  8. java集合-HashTable

    概述 和 HashMap 一样,Hashtable 也是一个散列表,它存储的内容是键值对. Hashtable 在 Java 中的定义为: public class Hashtable<K,V& ...

  9. java遍历hashTable

    //获取key值 Enumeration k = lovResults.keys();while(k.hasMoreElements()){ System.out.println(k.nextElem ...

随机推荐

  1. POJ 2886 线段树单点更新

    转载自:http://blog.csdn.net/sdj222555/article/details/6878651 反素数拓展参照:http://blog.csdn.net/ACdreamers/a ...

  2. CAS 服务端数据库认证

    CAS-服务端数据库认证 数据认证需要相关的jar包: cas-server-support-jdbc-x.x.x.jar MySQL-connector-Java-x.x.x-bin.jar 修改C ...

  3. static 关键字介绍

    大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立.然而在某些时候,我们更希望该类所有的对象共享同一个成员.此时就是 static 大显身手的时候了!! Java 中 ...

  4. 1.3 C++引用(Reference)

    参考:http://www.weixueyuan.net/view/6328.html 总结: 引用是变量的另外一个别名,不是指针,与原变量名同指相同的内存.可以原变量的值. 在函数中作为形参可以修改 ...

  5. RNN - LSTM - GRU

    循环神经网络 (Recurrent Neural Network,RNN) 是一类具有短期记忆能力的神经网络,因而常用于序列建模.本篇先总结 RNN 的基本概念,以及其训练中时常遇到梯度爆炸和梯度消失 ...

  6. Final阶段第1周/共1周 Scrum立会报告+燃尽图 03

    作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2482] 版本控制:https://git.coding.net/liuyy08 ...

  7. tomcat catalina.out(一,windows下的catalina.out)

    最近在研究项目时,发现linux操作系统中,catalina_home/logs/catalina.out的文件有几个G的大小,便上网查了下这个文件的生成方式及如何避免,下面是我整理的材料: 之前我们 ...

  8. ABP .Net Core To Json序列化配置

     一. 前言 我们采用ABP架构用MVC Controller或Web API返回给前端结果ToJson序列化后得到的属性命名都是采用js的驼峰格式,即首字母小写,后面单词首字母大写的格式(如:后台属 ...

  9. 类似select下拉选择框同时又支持手动输入的元素 datalist 介绍。

    有时候我们会有这样的需求,通过使用下拉菜单给用户一定的选择范围,同时又可以使用户在找不到选择项的时候手动输入.这个时候我们就需要用到html5的datalist属性了. datalist包含<o ...

  10. UITableViewCell的高度与UILabel自适应

    UITableViewCell内部只放了一个UILabel,Cell的高度随着UILabel内容的高度变化而变化,可重写UITableView的委托方法动态调整高度,还要设置UILabel.numbe ...