首页编程java编程java中hashtable是什么,hashtable是什么

java中hashtable是什么,hashtable是什么

编程之家2023-10-1394次浏览

各位老铁们好,相信很多人对java中hashtable是什么都不是特别的了解,因此呢,今天就来为大家分享下关于java中hashtable是什么以及hashtable是什么的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!

java中hashtable是什么,hashtable是什么

Java中HashMap和Hashtable及HashSet的区别

hastTable和hashMap的区别:

(1)Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。

(2)这个不同即是最重要的一点:Hashtable中的方法是同步的,而HashMap方法(在缺省情况下)是非同步的。即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;而对于HashMap,则需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解决:

java中hashtable是什么,hashtable是什么

Map Collections.synchronizedMap(Map m)

这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。

(3)只有HashMap可以让你将空值作为一个表的条目的key或value。HashMap中只有一条记录可以是一个空的key,但任意数量的条目可以是空的value。这就是说,如果在表中没有发现搜索键,或者如果发现了搜索键,但它是一个空的值,那么get()将返回null。如果有必要,用containKey()方法来区别这两种情况。

java中hashtable是什么,hashtable是什么

其它的一些资料:

1.HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样。(最主要的区别)

2.HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以,只容许有一个null值的key,可以有多个null值的value)。

3.HashTable有一个contains(Object value),功能和containsValue(Object value)功能一样。

4.HashTable使用Enumeration,HashMap使用Iterator。

以上只是表面的不同,它们的实现也有很大的不同。

5.HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

6.哈希值的使用不同,HashTable直接使用对象的hashCode,代码是这样的:

int hash= key.hashCode();

int index=(hash& 0x7FFFFFFF)% tab.length;

而HashMap重新计算hash值,而且用与代替求模:

int hash= hash(k);

int i= indexFor(hash, table.length);

static int hash(Object x){

int h= x.hashCode();

h+=~(h<< 9);

h ^=(h>>> 14);

h+=(h<< 4);

h ^=(h>>> 10);

return h;

}

static int indexFor(int h, int length){

return h&(length-1);

}

以上只是一些比较突出的区别,当然他们的实现上还是有很多不同的,比如

HashMap对null的操作。

hashtable是什么

Hashtable类基于 IDictionary接口,因此该集合中的每一元素是键和值对。

Hashtable由包含集合元素的存储桶组成。存储桶是 Hashtable中各元素的虚拟子组,与大多数集合中进行的搜索和检索相比,它可令搜索和检索更简单、更快速。每一存储桶都与一个哈希代码关联,该哈希代码是使用哈希函数生成的并基于该元素的键。

哈希函数是基于键返回数值哈希代码的算法。键是正被存储的对象的某一属性的值。哈希函数必须始终为相同的键返回相同的哈希代码。一个哈希函数能够为两个不同的键生成相同的哈希代码,但从哈希表检索元素时,为每一唯一键生成唯一哈希代码的哈希函数将令性能更佳。

在 Hashtable中用作元素的每一对象必须能够使用 Object.GetHashCode方法的实现为其自身生成哈希代码。但是,还可以通过使用 Hashtable构造函数(该构造函数将 IHashCodeProvider实现作为其参数之一接受),为 Hashtable中的所有元素指定一个哈希函数。

在将一个对象添加到 Hashtable时,它被存储在存储桶中,该存储桶与匹配该对象的哈希代码的哈希代码关联。当在 Hashtable内搜索一个值时,为该值生成哈希代码,并且搜索与该哈希代码关联的存储桶。

例如,一个字符串的哈希函数可以采用该字符串中每一字符的 ASCII代码并它们添加到一起来生成一个哈希代码。字符串“picnic”将具有与字符串“basket”的哈希代码不同的哈希代码;因此,字符串“picnic”和“basket”将处于不同的存储桶中。与之相比,“stressed”和“desserts”将具有相同的哈希代码并将处于相同的存储桶中。

using System;

using System.Collections;

public class SamplesHashtable

{

public static void Main()

{

// Creates and initializes a new Hashtable.

Hashtable myHT= new Hashtable();

myHT.Add("First","3");

myHT.Add("Second","2");

myHT.Add("Third","1");

// Displays the properties and values of the Hashtable.

Console.WriteLine("myHT");

Console.WriteLine(" Count:{0}", myHT.Count);

Console.WriteLine(myHT["First"]);//***也可以这它!

Console.WriteLine(" Keys and Values:");

PrintKeysAndValues( myHT);

}

public static void PrintKeysAndValues( Hashtable myList)

{

IDictionaryEnumerator myEnumerator= myList.GetEnumerator();

Console.WriteLine("\t-KEY-\t-VALUE-");

while( myEnumerator.MoveNext())

Console.WriteLine("\t{0}:\t{1}", myEnumerator.Key, myEnumerator.Value);

}

}

2.hash map和hash-table的区别

第一个区别就先来说说继承关系吧

如果你baidu一下,会发现网上的大致说法与“由于Java发展的历史原因。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。”相同。

这种说法没有错,但是不够准确,特别是对于我们这种大众菜鸟来说,如果不去深究的话,可能就会造成一些理解上的差异。简单的认为Hashtable没有继承Map接口。

我们可以参考一下最新的JDK1.6的源码,看看这两个类的定义:

publicclassHashtable<K,V>extendsDictionary<K,V>implementsMap<K,V>,Cloneable,java.io.Serializable{…}

publicclassHashMap<K,V>extendsAbstractMap<K,V>implementsMap<K,V>,Cloneable,Serializable{…}

可以看到hashtable也是继承了Map接口。

它们的不同是Hashtable(since JDK1.0)就继承了Dictionary这个抽象类,

而HashMap(since JDK1.2)继承的则是AbstractMap这个抽象类。

第二个区别我们从同步和并发性上来说说它们两个的不同。

可以通过这两个类得源码来分析,Hashtable中的主要方法都做了同步处理,而HashMap则没有。

可以说Hashtable在默认情况支持同步,而HashMap在默认情况下是不支持的。

我们在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

对HashMap的同步处理可以使用Collections类提供的synchronizedMap静态方法;

或者直接使用JDK5.0之后提供的java.util.concurrent包里的ConcurrentHashMap类。

第三个区别就是它们对于null值的处理方式了。

我们依然能够从源代码中得知,Hashtable中,key和value都不允许出现null值。

publicsynchronizedVput(Kkey,Vvalue){

//Makesurethevalueisnotnull

if(value==null){

thrownewNullPointerException();

}

//Makessurethekeyisnotalreadyinthehashtable.

Entrytab[]=table;

inthash=

key.hashCode();

intindex=(hash&0x7FFFFFFF)%tab.length;

//…

}

在我们使用上面的方法时,

如参数value为null,可以从代码中直接看出程序会抛出NullPointerException;

而在key为null时,则会在“int hash=

key.hashCode();“这段计算Hash值的过程中抛出NullPointerException。

而在在HashMap中,允许null作为key存在,并且和其他key的特性一样,这样的null值key只能有一个;

另外HashMap允许多个value为null。

这样大家就要注意了,HashMap中就不能用get(key)方法来判断HashMap中是否存在某个key,因为value为null和不存在该key的Entry都会返回null值,而应该用containsKey()方法来判断了。

import

java.util.HashMap;

importjava.util.Map;

import

java.util.Map.Entry;

publicclassTestCase

{

publicstaticvoidmain(String[]args){

Map<Integer,String>

hashMap=newHashMap<Integer,String>();

hashMap.put(0,null);

hashMap.put(1,

"one");

hashMap.put(2,

"two");

hashMap.put(null,

"null");

for(Entry<Integer,

String>e:hashMap.entrySet()){

System.out.println("Key:

"+e.getKey()+"--Value:"+e.getValue());

}

System.out.println(hashMap.get(0));

System.out.println(hashMap.get(4));

System.out.println("Contains

key0?:"+hashMap.containsKey(0));

System.out.println("Contains

key4?:"+hashMap.containsKey(4));

System.out.println("Contains

valuenull?:"+hashMap.containsValue(null));

}

}

结果:

Key:null--Value:

null

Key:0--Value:null

Key:1--Value:one

Key:2--Value:two

null

null

Containskey0?:true

Containskey4?

:false

Containsvaluenull?

:true

第四个不同就是它们两个Hash值的获取方式了。

还是通过源代码源代码,Hashtable是直接使用key对象的hash值。

publicsynchronizedVput(Kkey,Vvalue){

//Makesurethevalueisnotnull

if(value==null){

thrownewNullPointerException();

}

//Makessurethekeyisnotalreadyinthehashtable.

Entrytab[]=table;

inthash=key.hashCode();//hashcode

intindex=(hash&0x7FFFFFFF)%tab.length;

//…

}

而HashMap则是利用key对象的hash值重新计算一个新的hash值。

publicVput(Kkey,Vvalue){

if(key==null)

returnputForNullKey(value);

inthash=hash(key.hashCode());//hashcode

inti=indexFor(hash,table.length);

//…

}

staticinthash(inth)

{

h^=(h>>>20)^(h>>>12);

returnh^(h>>>7)^(h>>>4);

}

第五个不同就是Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。

HashMap中内部数组的初始容量是16,加载因子为0.75,而且数组容量增容后也要是2指数次幂:

/**

*Thedefault

initialcapacity-MUSTbeapoweroftwo.

*/

staticfinalint

DEFAULT_INITIAL_CAPACITY=16;

/**

*Theloadfactor

usedwhennonespecifiedinconstructor.

*/

staticfinalfloat

DEFAULT_LOAD_FACTOR=0.75f;

HashTable中的内部数组的初始容量是11,加载因子也是0.75数组的增容方式为(oldCapacity* 2+ 1):

publicHashtable(){

this(11,

0.75f);

}

protectedvoid

rehash(){

int

oldCapacity=table.length;

Entry[]

oldMap=table;

int

newCapacity=oldCapacity*2+1;

//…

}

第六个不同我们从它们两个遍历方式的内部实现上来说。

Hashtable HashMap都使用了Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式。

第七个不同时它们的拷贝构造函数的不同。

依然是通过查看源码,可以发现它们两个对于拷贝函数初始容量的不同值。

HashMap的实现是:

public

HashMap(Map<?extendsK,?extendsV>m){

this(Math.max((int)

(m.size()/DEFAULT_LOAD_FACTOR)+1,DEFAULT_INITIAL_CAPACITY),DEFAULT_LOAD_FACTOR);

putAllForCreate(m);

}

而Hashtable的实现是:

public

Hashtable(Map<?extendsK,?extendsV>t){

this(Math.max(2*t.size(),

11),0.75f);

putAll(t);

}

关于java中hashtable是什么和hashtable是什么的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

ipad怎么下电影 ipad怎么下载电影到u盘java主要学什么,java主要学习哪些内容