牛客干货Java精华笔记之数据结构

正在学习Java?

想要对Java数据结构有更多了解?

下拉阅读这份《Java精华笔记之数据结构》,纯干货!

Java精华笔记之数据结构

牛客用户:IT、小农民

大家应该熟悉使用java.util包里面的各种数据结构,常用的数据结构有线性表、链表、哈希表等,在我们进行java开发时,JDK已经给我们提供了一系列的相应类来实现基本的数据结构。

常用集合类的继承结构如下:

Collction

├List

│├LinkdList

│├ArrayList

│└Vctor

│ └Stack

└St

Map

├Hashtabl

├HashMap

└WakHashMap

Collction是最近本的集合接口,一个Collction代表一组Objct(Elmnts)。java的SDK不提供直接继承Collction的类,而是继承Collction的子接口如:List、St。

这里Collction、List、St和Map都是接口(Intrfac),不是具体的实现类。根据上图可以直到List实现类有ArrayList和LiskdList和Vctor。

Collction元素如何遍历?不论Collction的实际类型是什么,它都支持一个itrator()的方法,返回一个迭代子,是该迭代子可以逐一访问Collction中每一个元素。代码如下:

Itratorit=c.itrator();//获取一个迭代子  whil(it.hasNxt()){  Objctobj=it.nxt();//获取下一个元素  Systm.out.println(obj);}

由Collction接口派生的两个接口是List和St。

主要方法:

List接口

List是有序的Collction,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。

和下面要提到的St不同,List允许有相同的元素。

除了具有Collction接口必备的itrator()方法外,List还提供一个listItrator()方法,返回一个ListItrator接口,和标准的Itrator接口相比,ListItrator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。

实现List接口的常用类有LinkdList,ArrayList,Vctor和Stack。

主要方法:

voidadd(intindx,Objctlmnt)在指定位置上添加一个对象

boolanaddAll(intindx,Collctionc)将集合c的元素添加到指定的位置

Objctgt(intindx)返回List中指定位置的元素

intindxOf(Objcto)返回第一个出现元素o的位置.

Objctrmovint(intindx)删除指定位置的元素

Objctst(intindx,Objctlmnt)用元素lmnt取代位置indx上的元素,返回被取代的元素

LinkdList类

LinkdList实现了List接口,允许null元素。此外LinkdList提供额外的gt,rmov,insrt方法在LinkdList的首部或尾部。这些操作使LinkdList可被用作堆栈(stack),队列(quu)或双向队列(dqu)。

注意LinkdList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:

Listlist=Collctions.synchronizdList(nwLinkdList(...));

ArrayList类

ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。

siz,isEmpty,gt,st方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。

每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用nsurCapacity方法来增加ArrayList的容量以提高插入效率。

和LinkdList一样,ArrayList也是非同步的(unsynchronizd)。

主要方法:

Boolanadd(Objcto)将指定元素添加到列表的末尾

Boolanadd(intindx,Objctlmnt)在列表中指定位置加入指定元素

BoolanaddAll(Collctionc)将指定集合添加到列表末尾

BoolanaddAll(intindx,Collctionc)在列表中指定位置加入指定集合

Boolanclar()删除列表中所有元素

Boolanclon()返回该列表实例的一个拷贝

Boolancontains(Objcto)判断列表中是否包含元素

BoolannsurCapacity(intm)增加列表的容量,如果必须,该列表能够容纳m个元素

Objctgt(intindx)返回列表中指定位置的元素

IntindxOf(Objctlm)在列表中查找指定元素的下标

Intsiz()返回当前列表的元素个数

Vctor类

Vctor非常类似ArrayList,但是Vctor是同步的。由Vctor创建的Itrator,虽然和ArrayList创建的Itrator是同一接口,但是,因为Vctor是同步的,当一个Itrator被创建而且正在被使用,另一个线程改变了Vctor的状态(例如,添加或删除了一些元素),这时调用Itrator的方法时将抛出ConcurrntModificationExcption,因此必须捕获该异常。

Stack类

Stack继承自Vctor,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vctor得以被当作堆栈使用。基本的push和pop方法,还有pk方法得到栈顶的元素,mpty方法测试堆栈是否为空,sarch方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

St接口

St是一种不包含重复的元素的Collction,即任意的两个元素1和2都有1.quals(2)=fals,St最多有一个null元素。

很明显,St的构造函数有一个约束条件,传入的Collction参数不能包含重复的元素。

请注意:必须小心操作可变对象(MutablObjct)。如果一个St中的可变元素改变了自身状态导致Objct.quals(Objct)=tru将导致一些问题。

Map接口

请注意,Map没有继承Collction接口,Map提供ky到valu的映射。一个Map中不能包含相同的ky,每个ky只能映射一个valu。Map接口提供3种集合的视图,Map的内容可以被当作一组ky集合,一组valu集合,或者一组ky-valu映射。

主要方法:

boolanquals(Objcto)比较对象

boolanrmov(Objcto)删除一个对象

put(Objctky,Objctvalu)添加ky和valu

Hashtabl类

Hashtabl继承Map接口,实现一个ky-valu映射的哈希表。任何非空(non-null)的对象都可作为ky或者valu。

添加数据使用put(ky,valu),取出数据使用gt(ky),这两个基本操作的时间开销为常数。

Hashtabl通过initialcapacity和loadfactor两个参数调整性能。通常缺省的loadfactor0.75较好地实现了时间和空间的均衡。增大loadfactor可以节省空间但相应的查找时间将增大,这会影响像gt和put这样的操作。

使用Hashtabl的简单示例如下,将1,2,3放到Hashtabl中,他们的ky分别是”on”,”two”,”thr”:

Hashtablnumbrs=nwHashtabl();      numbrs.put(“on”,nwIntgr(1));      numbrs.put(“two”,nwIntgr(2));      numbrs.put(“thr”,nwIntgr(3));

要取出一个数,比如2,用相应的ky:

Intgrn=(Intgr)numbrs.gt(“two”);    Systm.out.println(“two=”+n);

由于作为ky的对象将通过计算其散列函数来确定与之对应的valu的位置,因此任何作为ky的对象都必须实现hashCod和quals方法。hashCod和quals方法继承自根类Objct,如果你用自定义的类当作ky的话,要相当小心,按照散列函数的定义,如果两个对象相同,即obj1.quals(obj2)=tru,则它们的hashCod必须相同,但如果两个对象不同,则它们的hashCod不一定不同,如果两个不同对象的hashCod相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCod()方法,能加快哈希表的操作。

如果相同的对象有不同的hashCod,对哈希表的操作会出现意想不到的结果(期待的gt方法返回null),要避免这种问题,只需要牢记一条:要同时复写quals方法和hashCod方法,而不要只写其中一个。

Hashtabl是同步的。

HashMap类

HashMap和Hashtabl类似,不同之处在于HashMap是非同步的,并且允许null,即nullvalu和nullky。,但是将HashMap视为Collction时(valus()方法可返回Collction),其迭代子操作时间开销和HashMap的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者loadfactor过低。

WakHashMap类

WakHashMap是一种改进的HashMap,它对ky实行“弱引用”,如果一个ky不再被外部所引用,那么该ky可以被GC回收。

Collctions和Arrays

java集合中里面有两个类为Collcitons和Arrays,这是JCF(JavaCollctionsFramwork)里面功能强大的工具。提供的算法如下:

binarySarch:折半查找。

sort:排序,只是一种类似快速排序的方法,效率仍然是O(n*logn),但是一种稳定的排序方法。

rvs:线性表进行逆序操作。

rotat:以摸个元素为轴心将线性表“旋转”。

swap:交换一个线性表中的2个元素位置。

Collctions还有一个重要功能就是“封装器”(Wrappr),它提供了一些方法可以把一个集合转换成一个特殊的集合,如下:

unmodifiablXXX:转换成只读集合,这里XXX代表六种基本集合接口:Collction、List、Map、St、SortdMap和SortdSt。如果你对只读集合进行插入删除操作,将会抛出UnsupportdOprationExcption异常。synchronizdXXX:转换成同步集合。singlton:创建一个仅有一个元素的集合,这里singlton生成的是单元素St,singltonList和singltonMap分别生成单元素的List和Map。空集:由Collctions的静态属性EMPTY_SET、EMPTY_LIST和EMPTY_MAP表示。

总结

1、ArrayList:元素单个,效率高,多用于查询2、Vctor:元素单个,线程安全,多用于查询3、LinkdList:元素单个,多用于插入和删除

4、HashMap:元素成对,元素可为空

5、HashTabl:元素成对,线程安全,元素不可为空

如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkdList,如果需要快速随机访问元素,应该使用ArrayList。

如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。

要特别注意对哈希表的操作,作为ky的对象要正确复写quals和hashCod方法。

▼点击阅读原文获得实用干货









































看白癜风的医院哪个好
白癜风治疗中心



转载请注明:http://www.92nongye.com/tlfc/204615198.html