了解下JAVA的Java汇合进修(十六) HashSet具体先容(源码剖析)和利用示例
C#是不行的,比如说美国的航天飞船里就有java开发的程序以上是我的愚见,其实不管那种语言,你学好了,都能找到好的工作,这一章,我们对HashSet举行进修。
我们先对HashSet有个全体熟悉,然后再进修它的源码,最初再经由过程实例来学会利用HashSet。
第1部分HashSet先容
HashSet简介
HashSet是一个没有反复元素的汇合。
它是由HashMap完成的,不包管元素的按次,并且HashSet同意利用null元素。
HashSet长短同步的。假如多个线程同时会见一个哈希set,而个中最少一个线程修正了该set,那末它必需坚持内部同步。这一般是经由过程对天然封装该set的对象实行同步操纵来完成的。假如不存在如许的对象,则应当利用Collections.synchronizedSet办法来“包装”set。最幸亏创立时完成这一操纵,以避免对该set举行不测的分歧步会见:
Sets=Collections.synchronizedSet(newHashSet(...));
HashSet经由过程iterator()前往的迭代器是fail-fast的。
HashSet的承继干系以下:
java.lang.Object
java.util.AbstractCollection<E>
java.util.AbstractSet<E>
java.util.HashSet<E>
publicclassHashSet<E>
extendsAbstractSet<E>
implementsSet<E>,Cloneable,java.io.Serializable{}HashSet与Map干系以下图:
检察本栏目更多出色内容:http://www.bianceng.cn/Programming/Java/
HashSet的机关函数
//默许机关函数
publicHashSet()
//带汇合的机关函数
publicHashSet(Collection<?extendsE>c)
//指定HashSet初始容量和加载因子的机关函数
publicHashSet(intinitialCapacity,floatloadFactor)
//指定HashSet初始容量的机关函数
publicHashSet(intinitialCapacity)
//指定HashSet初始容量和加载因子的机关函数,dummy没有任何感化
HashSet(intinitialCapacity,floatloadFactor,booleandummy)HashSet的次要API
booleanadd(Eobject)
voidclear()
Objectclone()
booleancontains(Objectobject)
booleanisEmpty()
Iterator<E>iterator()
booleanremove(Objectobject)
intsize()第2部分HashSet源码剖析
为了更懂得HashSet的道理,上面对HashSet源码代码作出剖析。
packagejava.util;
publicclassHashSet<E>
extendsAbstractSet<E>
implementsSet<E>,Cloneable,java.io.Serializable
{
staticfinallongserialVersionUID=-5024744406713321676L;
//HashSet是经由过程map(HashMap对象)保留内容的
privatetransientHashMap<E,Object>map;
//PRESENT是向map中拔出key-value对应的value
//由于HashSet中只必要用到key,而HashMap是key-value键值对;
//以是,向map中增加键值对时,键值对的值流动是PRESENT
privatestaticfinalObjectPRESENT=newObject();
//默许机关函数
publicHashSet(){
//挪用HashMap的默许机关函数,创立map
map=newHashMap<E,Object>();
}
//带汇合的机关函数
publicHashSet(Collection<?extendsE>c){
//创立map。
//为何要挪用Math.max((int)(c.size()/.75f)+1,16),从(c.size()/.75f)+1和16当选择一个对照年夜的树呢?
//起首,申明(c.size()/.75f)+1
//由于从HashMap的效力(工夫本钱和空间本钱)思索,HashMap的加载因子是0.75。
//当HashMap的“阈值”(阈值=HashMap总的巨细*加载因子)<“HashMap实践巨细”时,
//就必要将HashMap的容量翻倍。
//以是,(c.size()/.75f)+1盘算出来的恰好是总的空间巨细。
//接上去,申明为何是16。
//HashMap的总的巨细,必需是2的指数倍。若创立HashMap时,指定的巨细不是2的指数倍;
//HashMap的机关函数中也会从头盘算,找出比“指定巨细”年夜的最小的2的指数倍的数。
//以是,这里指定为16是从功能思索。制止反复盘算。
map=newHashMap<E,Object>(Math.max((int)(c.size()/.75f)+1,16));
//将汇合(c)中的全体元素增加到HashSet中
addAll(c);
}
//指定HashSet初始容量和加载因子的机关函数
publicHashSet(intinitialCapacity,floatloadFactor){
map=newHashMap<E,Object>(initialCapacity,loadFactor);
}
//指定HashSet初始容量的机关函数
publicHashSet(intinitialCapacity){
map=newHashMap<E,Object>(initialCapacity);
}
HashSet(intinitialCapacity,floatloadFactor,booleandummy){
map=newLinkedHashMap<E,Object>(initialCapacity,loadFactor);
}
//前往HashSet的迭代器
publicIterator<E>iterator(){
//实践上前往的是HashMap的“key汇合的迭代器”
returnmap.keySet().iterator();
}
publicintsize(){
returnmap.size();
}
publicbooleanisEmpty(){
returnmap.isEmpty();
}
publicbooleancontains(Objecto){
returnmap.containsKey(o);
}
//将元素(e)增加到HashSet中
publicbooleanadd(Ee){
returnmap.put(e,PRESENT)==null;
}
//删除HashSet中的元素(o)
publicbooleanremove(Objecto){
returnmap.remove(o)==PRESENT;
}
publicvoidclear(){
map.clear();
}
//克隆一个HashSet,并前往Object对象
publicObjectclone(){
try{
HashSet<E>newSet=(HashSet<E>)super.clone();
newSet.map=(HashMap<E,Object>)map.clone();
returnnewSet;
}catch(CloneNotSupportedExceptione){
thrownewInternalError();
}
}
//java.io.Serializable的写进函数
//将HashSet的“总的容量,加载因子,实践容量,一切的元素”都写进到输入流中
privatevoidwriteObject(java.io.ObjectOutputStreams)
throwsjava.io.IOException{
//Writeoutanyhiddenserializationmagic
s.defaultWriteObject();
//WriteoutHashMapcapacityandloadfactor
s.writeInt(map.capacity());
s.writeFloat(map.loadFactor());
//Writeoutsize
s.writeInt(map.size());
//Writeoutallelementsintheproperorder.
for(Iteratori=map.keySet().iterator();i.hasNext();)
s.writeObject(i.next());
}
//java.io.Serializable的读取函数
//将HashSet的“总的容量,加载因子,实践容量,一切的元素”顺次读出
privatevoidreadObject(java.io.ObjectInputStreams)
throwsjava.io.IOException,ClassNotFoundException{
//Readinanyhiddenserializationmagic
s.defaultReadObject();
//ReadinHashMapcapacityandloadfactorandcreatebackingHashMap
intcapacity=s.readInt();
floatloadFactor=s.readFloat();
map=(((HashSet)this)instanceofLinkedHashSet?
newLinkedHashMap<E,Object>(capacity,loadFactor):
newHashMap<E,Object>(capacity,loadFactor));
//Readinsize
intsize=s.readInt();
//Readinallelementsintheproperorder.
for(inti=0;i<size;i++){
Ee=(E)s.readObject();
map.put(e,PRESENT);
}
}
}申明:
<p>
恰恰证明了java的简单,要不怎么没有通过c/c++来搞个这种框架? 象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。 如果要向java web方向发展也要吧看看《Java web从入门到精通》学完再到《Struts2.0入门到精通》这样你差不多就把代码给学完了。有兴趣可以看一些设计模块和框架的包等等。 在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。 接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。 关于设计模式的资料,还是向大家推荐banq的网站 http://www.jdon.com/,他把GOF的23种模式以通俗易懂的方式诠释出来,纯Java描述,真是经典中的经典。 是一种使用者不需花费很多时间学习的语言 是一种将安全性(Security)列为第一优先考虑的语言 Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。 自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。
页:
[1]