|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
首先java功能强大的背后是其复杂性,就拿web来说,当今流行的框架有很多,什么struts,spring,jQuery等等,而这无疑增加了java的复杂性。
Hashtable简介
Hashtable一样是基于哈希表完成的,一样每一个元素是一个key-value对,其外部也是经由过程单链表办理抵触成绩,容量不敷(凌驾了阀值)时,一样会主动增加。
Hashtable也是JDK1.0引进的类,是线程平安的,能用于多线程情况中。
Hashtable一样完成了Serializable接口,它撑持序列化,完成了Cloneable接口,能被克隆。
HashTable源码分析
Hashtable的源码的良多完成都与HashMap差未几,源码以下(到场了对照具体的正文):- packagejava.util;
- importjava.io.*;
- publicclassHashtable<K,V>
- extendsDictionary<K,V>
- implementsMap<K,V>,Cloneable,java.io.Serializable{
- //保留key-value的数组。
- //Hashtable一样接纳单链表办理抵触,每个Entry实质上是一个单向链表
- privatetransientEntry[]table;
- //Hashtable中键值对的数目
- privatetransientintcount;
- //阈值,用于判别是不是必要调剂Hashtable的容量(threshold=容量*加载因子)
- privateintthreshold;
- //加载因子
- privatefloatloadFactor;
- //Hashtable被改动的次数,用于fail-fast机制的完成
- privatetransientintmodCount=0;
- //序列版本号
- privatestaticfinallongserialVersionUID=1421746759512286392L;
- //指定“容量巨细”和“加载因子”的机关函数
- publicHashtable(intinitialCapacity,floatloadFactor){
- if(initialCapacity<0)
- thrownewIllegalArgumentException("IllegalCapacity:"+
- initialCapacity);
- if(loadFactor<=0||Float.isNaN(loadFactor))
- thrownewIllegalArgumentException("IllegalLoad:"+loadFactor);
- if(initialCapacity==0)
- initialCapacity=1;
- this.loadFactor=loadFactor;
- table=newEntry[initialCapacity];
- threshold=(int)(initialCapacity*loadFactor);
- }
- //指定“容量巨细”的机关函数
- publicHashtable(intinitialCapacity){
- this(initialCapacity,0.75f);
- }
- //默许机关函数。
- publicHashtable(){
- //默许机关函数,指定的容量巨细是11;加载因子是0.75
- this(11,0.75f);
- }
- //包括“子Map”的机关函数
- publicHashtable(Map<?extendsK,?extendsV>t){
- this(Math.max(2*t.size(),11),0.75f);
- //将“子Map”的全体元素都增加到Hashtable中
- putAll(t);
- }
- publicsynchronizedintsize(){
- returncount;
- }
- publicsynchronizedbooleanisEmpty(){
- returncount==0;
- }
- //前往“一切key”的列举对象
- publicsynchronizedEnumeration<K>keys(){
- returnthis.<K>getEnumeration(KEYS);
- }
- //前往“一切value”的列举对象
- publicsynchronizedEnumeration<V>elements(){
- returnthis.<V>getEnumeration(VALUES);
- }
- //判别Hashtable是不是包括“值(value)”
- publicsynchronizedbooleancontains(Objectvalue){
- //注重,Hashtable中的value不克不及是null,
- //如果null的话,抛出非常!
- if(value==null){
- thrownewNullPointerException();
- }
- //从后向前遍历table数组中的元素(Entry)
- //关于每一个Entry(单向链表),逐一遍历,判别节点的值是不是即是value
- Entrytab[]=table;
- for(inti=tab.length;i-->0;){
- for(Entry<K,V>e=tab[i];e!=null;e=e.next){
- if(e.value.equals(value)){
- returntrue;
- }
- }
- }
- returnfalse;
- }
- publicbooleancontainsValue(Objectvalue){
- returncontains(value);
- }
- //判别Hashtable是不是包括key
- publicsynchronizedbooleancontainsKey(Objectkey){
- Entrytab[]=table;
- //盘算hash值,间接用key的hashCode取代
- inthash=key.hashCode();
- //盘算在数组中的索引值
- intindex=(hash&0x7FFFFFFF)%tab.length;
- //找到“key对应的Entry(链表)”,然后在链表中找出“哈希值”和“键值”与key都相称的元素
- for(Entry<K,V>e=tab[index];e!=null;e=e.next){
- if((e.hash==hash)&&e.key.equals(key)){
- returntrue;
- }
- }
- returnfalse;
- }
- //前往key对应的value,没有的话前往null
- publicsynchronizedVget(Objectkey){
- Entrytab[]=table;
- inthash=key.hashCode();
- //盘算索引值,
- intindex=(hash&0x7FFFFFFF)%tab.length;
- //找到“key对应的Entry(链表)”,然后在链表中找出“哈希值”和“键值”与key都相称的元素
- for(Entry<K,V>e=tab[index];e!=null;e=e.next){
- if((e.hash==hash)&&e.key.equals(key)){
- returne.value;
- }
- }
- returnnull;
- }
- //调剂Hashtable的长度,将长度酿成本来的2倍+1
- protectedvoidrehash(){
- intoldCapacity=table.length;
- Entry[]oldMap=table;
- //创立新容量巨细的Entry数组
- intnewCapacity=oldCapacity*2+1;
- Entry[]newMap=newEntry[newCapacity];
- modCount++;
- threshold=(int)(newCapacity*loadFactor);
- table=newMap;
- //将“旧的Hashtable”中的元素复制到“新的Hashtable”中
- for(inti=oldCapacity;i-->0;){
- for(Entry<K,V>old=oldMap[i];old!=null;){
- Entry<K,V>e=old;
- old=old.next;
- //从头盘算index
- intindex=(e.hash&0x7FFFFFFF)%newCapacity;
- e.next=newMap[index];
- newMap[index]=e;
- }
- }
- }
- //将“key-value”增加到Hashtable中
- publicsynchronizedVput(Kkey,Vvalue){
- //Hashtable中不克不及拔出value为null的元素!!!
- if(value==null){
- thrownewNullPointerException();
- }
- //若“Hashtable中已存在键为key的键值对”,
- //则用“新的value”交换“旧的value”
- Entrytab[]=table;
- inthash=key.hashCode();
- intindex=(hash&0x7FFFFFFF)%tab.length;
- for(Entry<K,V>e=tab[index];e!=null;e=e.next){
- if((e.hash==hash)&&e.key.equals(key)){
- Vold=e.value;
- e.value=value;
- returnold;
- }
- }
- //若“Hashtable中不存在键为key的键值对”,
- //将“修正统计数”+1
- modCount++;
- //若“Hashtable实践容量”>“阈值”(阈值=总的容量*加载因子)
- //则调剂Hashtable的巨细
- if(count>=threshold){
- rehash();
- tab=table;
- index=(hash&0x7FFFFFFF)%tab.length;
- }
- //将新的key-value对拔出到tab[index]处(即链表的头结点)
- Entry<K,V>e=tab[index];
- tab[index]=newEntry<K,V>(hash,key,value,e);
- count++;
- returnnull;
- }
- //删除Hashtable中键为key的元素
- publicsynchronizedVremove(Objectkey){
- Entrytab[]=table;
- inthash=key.hashCode();
- intindex=(hash&0x7FFFFFFF)%tab.length;
- //从table[index]链表中找出要删除的节点,并删除该节点。
- //由于是单链表,因而要保存带删省点的前一个节点,才干无效地删除节点
- for(Entry<K,V>e=tab[index],prev=null;e!=null;prev=e,e=e.next){
- if((e.hash==hash)&&e.key.equals(key)){
- modCount++;
- if(prev!=null){
- prev.next=e.next;
- }else{
- tab[index]=e.next;
- }
- count--;
- VoldValue=e.value;
- e.value=null;
- returnoldValue;
- }
- }
- returnnull;
- }
- //将“Map(t)”的中全体元素一一增加到Hashtable中
- publicsynchronizedvoidputAll(Map<?extendsK,?extendsV>t){
- for(Map.Entry<?extendsK,?extendsV>e:t.entrySet())
- put(e.getKey(),e.getValue());
- }
- //清空Hashtable
- //将Hashtable的table数组的值全体设为null
- //本栏目更多出色内容:http://www.bianceng.cn/Programming/Java/
- publicsynchronizedvoidclear(){
- Entrytab[]=table;
- modCount++;
- for(intindex=tab.length;--index>=0;)
- tab[index]=null;
- count=0;
- }
- //克隆一个Hashtable,并以Object的情势前往。
- publicsynchronizedObjectclone(){
- try{
- Hashtable<K,V>t=(Hashtable<K,V>)super.clone();
- t.table=newEntry[table.length];
- for(inti=table.length;i-->0;){
- t.table[i]=(table[i]!=null)
- ?(Entry<K,V>)table[i].clone():null;
- }
- t.keySet=null;
- t.entrySet=null;
- t.values=null;
- t.modCount=0;
- returnt;
- }catch(CloneNotSupportedExceptione){
- thrownewInternalError();
- }
- }
- publicsynchronizedStringtoString(){
- intmax=size()-1;
- if(max==-1)
- return"{}";
- StringBuildersb=newStringBuilder();
- Iterator<Map.Entry<K,V>>it=entrySet().iterator();
- sb.append({);
- for(inti=0;;i++){
- Map.Entry<K,V>e=it.next();
- Kkey=e.getKey();
- Vvalue=e.getValue();
- sb.append(key==this?"(thisMap)":key.toString());
- sb.append(=);
- sb.append(value==this?"(thisMap)":value.toString());
- if(i==max)
- returnsb.append(}).toString();
- sb.append(",");
- }
- }
- //猎取Hashtable的列举类对象
- //若Hashtable的实践巨细为0,则前往“空列举类”对象;
- //不然,前往一般的Enumerator的对象。
- private<T>Enumeration<T>getEnumeration(inttype){
- if(count==0){
- return(Enumeration<T>)emptyEnumerator;
- }else{
- returnnewEnumerator<T>(type,false);
- }
- }
- //猎取Hashtable的迭代器
- //若Hashtable的实践巨细为0,则前往“空迭代器”对象;
- //不然,前往一般的Enumerator的对象。(Enumerator完成了迭代器和列举两个接口)
- private<T>Iterator<T>getIterator(inttype){
- if(count==0){
- return(Iterator<T>)emptyIterator;
- }else{
- returnnewEnumerator<T>(type,true);
- }
- }
- //Hashtable的“key的汇合”。它是一个Set,没有反复元素
- privatetransientvolatileSet<K>keySet=null;
- //Hashtable的“key-value的汇合”。它是一个Set,没有反复元素
- privatetransientvolatileSet<Map.Entry<K,V>>entrySet=null;
- //Hashtable的“key-value的汇合”。它是一个Collection,能够有反复元素
- privatetransientvolatileCollection<V>values=null;
- //前往一个被synchronizedSet封装后的KeySet对象
- //synchronizedSet封装的目标是对KeySet的一切办法都增加synchronized,完成多线程同步
- publicSet<K>keySet(){
- if(keySet==null)
- keySet=Collections.synchronizedSet(newKeySet(),this);
- returnkeySet;
- }
- //Hashtable的Key的Set汇合。
- //KeySet承继于AbstractSet,以是,KeySet中的元素没有反复的。
- privateclassKeySetextendsAbstractSet<K>{
- publicIterator<K>iterator(){
- returngetIterator(KEYS);
- }
- publicintsize(){
- returncount;
- }
- publicbooleancontains(Objecto){
- returncontainsKey(o);
- }
- publicbooleanremove(Objecto){
- returnHashtable.this.remove(o)!=null;
- }
- publicvoidclear(){
- Hashtable.this.clear();
- }
- }
- //前往一个被synchronizedSet封装后的EntrySet对象
- //synchronizedSet封装的目标是对EntrySet的一切办法都增加synchronized,完成多线程同步
- publicSet<Map.Entry<K,V>>entrySet(){
- if(entrySet==null)
- entrySet=Collections.synchronizedSet(newEntrySet(),this);
- returnentrySet;
- }
- //Hashtable的Entry的Set汇合。
- //EntrySet承继于AbstractSet,以是,EntrySet中的元素没有反复的。
- privateclassEntrySetextendsAbstractSet<Map.Entry<K,V>>{
- publicIterator<Map.Entry<K,V>>iterator(){
- returngetIterator(ENTRIES);
- }
- publicbooleanadd(Map.Entry<K,V>o){
- returnsuper.add(o);
- }
- //查找EntrySet中是不是包括Object(0)
- //起首,在table中找到o对应的Entry链表
- //然后,查找Entry链表中是不是存在Object
- publicbooleancontains(Objecto){
- if(!(oinstanceofMap.Entry))
- returnfalse;
- Map.Entryentry=(Map.Entry)o;
- Objectkey=entry.getKey();
- Entry[]tab=table;
- inthash=key.hashCode();
- intindex=(hash&0x7FFFFFFF)%tab.length;
- for(Entrye=tab[index];e!=null;e=e.next)
- if(e.hash==hash&&e.equals(entry))
- returntrue;
- returnfalse;
- }
- //删除元素Object(0)
- //起首,在table中找到o对应的Entry链表
- //然后,删除链表中的元素Object
- publicbooleanremove(Objecto){
- if(!(oinstanceofMap.Entry))
- returnfalse;
- Map.Entry<K,V>entry=(Map.Entry<K,V>)o;
- Kkey=entry.getKey();
- Entry[]tab=table;
- inthash=key.hashCode();
- intindex=(hash&0x7FFFFFFF)%tab.length;
- for(Entry<K,V>e=tab[index],prev=null;e!=null;
- prev=e,e=e.next){
- if(e.hash==hash&&e.equals(entry)){
- modCount++;
- if(prev!=null)
- prev.next=e.next;
- else
- tab[index]=e.next;
- count--;
- e.value=null;
- returntrue;
- }
- }
- returnfalse;
- }
- publicintsize(){
- returncount;
- }
- publicvoidclear(){
- Hashtable.this.clear();
- }
- }
- //前往一个被synchronizedCollection封装后的ValueCollection对象
- //synchronizedCollection封装的目标是对ValueCollection的一切办法都增加synchronized,完成多线程同步
- publicCollection<V>values(){
- if(values==null)
- values=Collections.synchronizedCollection(newValueCollection(),
- this);
- returnvalues;
- }
- //Hashtable的value的Collection汇合。
- //ValueCollection承继于AbstractCollection,以是,ValueCollection中的元素能够反复的。
- privateclassValueCollectionextendsAbstractCollection<V>{
- publicIterator<V>iterator(){
- returngetIterator(VALUES);
- }
- publicintsize(){
- returncount;
- }
- publicbooleancontains(Objecto){
- returncontainsValue(o);
- }
- publicvoidclear(){
- Hashtable.this.clear();
- }
- }
- //从头equals()函数
- //若两个Hashtable的一切key-value键值对都相称,则判别它们两个相称
- publicsynchronizedbooleanequals(Objecto){
- if(o==this)
- returntrue;
- if(!(oinstanceofMap))
- returnfalse;
- Map<K,V>t=(Map<K,V>)o;
- if(t.size()!=size())
- returnfalse;
- try{
- //经由过程迭代器顺次掏出以后Hashtable的key-value键值对
- //并判别该键值对,存在于Hashtable中。
- //若不存在,则当即前往false;不然,遍历完“以后Hashtable”并前往true。
- Iterator<Map.Entry<K,V>>i=entrySet().iterator();
- while(i.hasNext()){
- Map.Entry<K,V>e=i.next();
- Kkey=e.getKey();
- Vvalue=e.getValue();
- if(value==null){
- if(!(t.get(key)==null&&t.containsKey(key)))
- returnfalse;
- }else{
- if(!value.equals(t.get(key)))
- returnfalse;
- }
- }
- }catch(ClassCastExceptionunused){
- returnfalse;
- }catch(NullPointerExceptionunused){
- returnfalse;
- }
- returntrue;
- }
- //盘算Entry的hashCode
- //若Hashtable的实践巨细为0大概加载因子<0,则前往0。
- //不然,前往“Hashtable中的每一个Entry的key和value的异或值的总和”。
- publicsynchronizedinthashCode(){
- inth=0;
- if(count==0||loadFactor<0)
- returnh;//Returnszero
- loadFactor=-loadFactor;//MarkhashCodecomputationinprogress
- Entry[]tab=table;
- for(inti=0;i<tab.length;i++)
- for(Entrye=tab[i];e!=null;e=e.next)
- h+=e.key.hashCode()^e.value.hashCode();
- loadFactor=-loadFactor;//MarkhashCodecomputationcomplete
- returnh;
- }
- //java.io.Serializable的写进函数
- //将Hashtable的“总的容量,实践容量,一切的Entry”都写进到输入流中
- privatesynchronizedvoidwriteObject(java.io.ObjectOutputStreams)
- throwsIOException
- {
- //Writeoutthelength,threshold,loadfactor
- s.defaultWriteObject();
- //Writeoutlength,countofelementsandthenthekey/valueobjects
- s.writeInt(table.length);
- s.writeInt(count);
- for(intindex=table.length-1;index>=0;index--){
- Entryentry=table[index];
- while(entry!=null){
- s.writeObject(entry.key);
- s.writeObject(entry.value);
- entry=entry.next;
- }
- }
- }
- //java.io.Serializable的读取函数:依据写进体例读出
- //将Hashtable的“总的容量,实践容量,一切的Entry”顺次读出
- privatevoidreadObject(java.io.ObjectInputStreams)
- throwsIOException,ClassNotFoundException
- {
- //Readinthelength,threshold,andloadfactor
- s.defaultReadObject();
- //Readtheoriginallengthofthearrayandnumberofelements
- intoriglength=s.readInt();
- intelements=s.readInt();
- //Computenewsizewithabitofroom5%togrowbut
- //nolargerthantheoriginalsize.Makethelength
- //oddifitslargeenough,thishelpsdistributetheentries.
- //Guardagainstthelengthendingupzero,thatsnotvalid.
- intlength=(int)(elements*loadFactor)+(elements/20)+3;
- if(length>elements&&(length&1)==0)
- length--;
- if(origlength>0&&length>origlength)
- length=origlength;
- Entry[]table=newEntry[length];
- count=0;
- //Readthenumberofelementsandthenallthekey/valueobjects
- for(;elements>0;elements--){
- Kkey=(K)s.readObject();
- Vvalue=(V)s.readObject();
- //synchcouldbeeliminatedforperformance
- reconstitutionPut(table,key,value);
- }
- this.table=table;
- }
- privatevoidreconstitutionPut(Entry[]tab,Kkey,Vvalue)
- throwsStreamCorruptedException
- {
- if(value==null){
- thrownewjava.io.StreamCorruptedException();
- }
- //Makessurethekeyisnotalreadyinthehashtable.
- //Thisshouldnothappenindeserializedversion.
- inthash=key.hashCode();
- intindex=(hash&0x7FFFFFFF)%tab.length;
- for(Entry<K,V>e=tab[index];e!=null;e=e.next){
- if((e.hash==hash)&&e.key.equals(key)){
- thrownewjava.io.StreamCorruptedException();
- }
- }
- //Createsthenewentry.
- Entry<K,V>e=tab[index];
- tab[index]=newEntry<K,V>(hash,key,value,e);
- count++;
- }
- //Hashtable的Entry节点,它实质上是一个单向链表。
- //也因而,我们才干揣度出Hashtable是由拉链法完成的散列表
- privatestaticclassEntry<K,V>implementsMap.Entry<K,V>{
- //哈希值
- inthash;
- Kkey;
- Vvalue;
- //指向的下一个Entry,即链表的下一个节点
- Entry<K,V>next;
- //机关函数
- protectedEntry(inthash,Kkey,Vvalue,Entry<K,V>next){
- this.hash=hash;
- this.key=key;
- this.value=value;
- this.next=next;
- }
- protectedObjectclone(){
- returnnewEntry<K,V>(hash,key,value,
- (next==null?null:(Entry<K,V>)next.clone()));
- }
- publicKgetKey(){
- returnkey;
- }
- publicVgetValue(){
- returnvalue;
- }
- //设置value。若value是null,则抛出非常。
- publicVsetValue(Vvalue){
- if(value==null)
- thrownewNullPointerException();
- VoldValue=this.value;
- this.value=value;
- returnoldValue;
- }
- //掩盖equals()办法,判别两个Entry是不是相称。
- //若两个Entry的key和value都相称,则以为它们相称。
- publicbooleanequals(Objecto){
- if(!(oinstanceofMap.Entry))
- returnfalse;
- Map.Entrye=(Map.Entry)o;
- return(key==null?e.getKey()==null:key.equals(e.getKey()))&&
- (value==null?e.getValue()==null:value.equals(e.getValue()));
- }
- publicinthashCode(){
- returnhash^(value==null?0:value.hashCode());
- }
- publicStringtoString(){
- returnkey.toString()+"="+value.toString();
- }
- }
- privatestaticfinalintKEYS=0;
- privatestaticfinalintVALUES=1;
- privatestaticfinalintENTRIES=2;
- //Enumerator的感化是供应了“经由过程elements()遍历Hashtable的接口”和“经由过程entrySet()遍历Hashtable的接口”。
- privateclassEnumerator<T>implementsEnumeration<T>,Iterator<T>{
- //指向Hashtable的table
- Entry[]table=Hashtable.this.table;
- //Hashtable的总的巨细
- intindex=table.length;
- Entry<K,V>entry=null;
- Entry<K,V>lastReturned=null;
- inttype;
- //Enumerator是“迭代器(Iterator)”仍是“列举类(Enumeration)”的标记
- //iterator为true,暗示它是迭代器;不然,是列举类。
- booleaniterator;
- //在将Enumerator看成迭代器利用时会用到,用来完成fail-fast机制。
- protectedintexpectedModCount=modCount;
- Enumerator(inttype,booleaniterator){
- this.type=type;
- this.iterator=iterator;
- }
- //从遍历table的数组的开端向前查找,直到找到不为null的Entry。
- publicbooleanhasMoreElements(){
- Entry<K,V>e=entry;
- inti=index;
- Entry[]t=table;
- /*Uselocalsforfasterloopiteration*/
- while(e==null&&i>0){
- e=t[--i];
- }
- entry=e;
- index=i;
- returne!=null;
- }
- //猎取下一个元素
- //注重:从hasMoreElements()和nextElement()能够看出“Hashtable的elements()遍历体例”
- //起首,从后向前的遍历table数组。table数组的每一个节点都是一个单向链表(Entry)。
- //然后,顺次向后遍历单向链表Entry。
- publicTnextElement(){
- Entry<K,V>et=entry;
- inti=index;
- Entry[]t=table;
- /*Uselocalsforfasterloopiteration*/
- while(et==null&&i>0){
- et=t[--i];
- }
- entry=et;
- index=i;
- if(et!=null){
- Entry<K,V>e=lastReturned=entry;
- entry=e.next;
- returntype==KEYS?(T)e.key:(type==VALUES?(T)e.value:(T)e);
- }
- thrownewNoSuchElementException("HashtableEnumerator");
- }
- //迭代器Iterator的判别是不是存鄙人一个元素
- //实践上,它是挪用的hasMoreElements()
- publicbooleanhasNext(){
- returnhasMoreElements();
- }
- //迭代器猎取下一个元素
- //实践上,它是挪用的nextElement()
- publicTnext(){
- if(modCount!=expectedModCount)
- thrownewConcurrentModificationException();
- returnnextElement();
- }
- //迭代器的remove()接口。
- //起首,它在table数组中找出要删除元素地点的Entry,
- //然后,删除单向链表Entry中的元素。
- publicvoidremove(){
- if(!iterator)
- thrownewUnsupportedOperationException();
- if(lastReturned==null)
- thrownewIllegalStateException("HashtableEnumerator");
- if(modCount!=expectedModCount)
- thrownewConcurrentModificationException();
- synchronized(Hashtable.this){
- Entry[]tab=Hashtable.this.table;
- intindex=(lastReturned.hash&0x7FFFFFFF)%tab.length;
- for(Entry<K,V>e=tab[index],prev=null;e!=null;
- prev=e,e=e.next){
- if(e==lastReturned){
- modCount++;
- expectedModCount++;
- if(prev==null)
- tab[index]=e.next;
- else
- prev.next=e.next;
- count--;
- lastReturned=null;
- return;
- }
- }
- thrownewConcurrentModificationException();
- }
- }
- }
- privatestaticEnumerationemptyEnumerator=newEmptyEnumerator();
- privatestaticIteratoremptyIterator=newEmptyIterator();
- //空列举类
- //当Hashtable的实践巨细为0;此时,又要经由过程Enumeration遍历Hashtable时,前往的是“空列举类”的对象。
- privatestaticclassEmptyEnumeratorimplementsEnumeration<Object>{
- EmptyEnumerator(){
- }
- //空列举类的hasMoreElements()一直前往false
- publicbooleanhasMoreElements(){
- returnfalse;
- }
- //空列举类的nextElement()抛出非常
- publicObjectnextElement(){
- thrownewNoSuchElementException("HashtableEnumerator");
- }
- }
- //空迭代器
- //当Hashtable的实践巨细为0;此时,又要经由过程迭代器遍历Hashtable时,前往的是“空迭代器”的对象。
- privatestaticclassEmptyIteratorimplementsIterator<Object>{
- EmptyIterator(){
- }
- publicbooleanhasNext(){
- returnfalse;
- }
- publicObjectnext(){
- thrownewNoSuchElementException("HashtableIterator");
- }
- publicvoidremove(){
- thrownewIllegalStateException("HashtableIterator");
- }
- }
- }
复制代码 几点总结
针对Hashtable,我们一样给出几点对照主要的总结,但要分离与HashMap的对照来总结。
<p>
为什么外国人还要写那些框架进行代码封装,他们不就是为了别人使用时可以更简单么!如果要达到一个企业级项目的不用框架是很难的。小一些的项目还行,大的光是MVC模式的设计的编码量就够大的了。还有性能方面,单轮windows,这个工具是微软写的,。 |
|