常見(jiàn)Java面試題和答案_第1頁(yè)
常見(jiàn)Java面試題和答案_第2頁(yè)
常見(jiàn)Java面試題和答案_第3頁(yè)
常見(jiàn)Java面試題和答案_第4頁(yè)
常見(jiàn)Java面試題和答案_第5頁(yè)
已閱讀5頁(yè),還剩131頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Interface與AbstractClass的區(qū)別

在Java語(yǔ)言中,abstractclass和interface是支持抽象類定義的兩種機(jī)制。

正是由于這兩種機(jī)制的存在,才賦予了Java強(qiáng)大的面向?qū)ο竽芰Αbstract

class和interface之間在對(duì)于抽象類定義的支持方面具有很大的相似性,甚至

可以相互替換,因此很多開(kāi)發(fā)者在進(jìn)行抽象類定義時(shí)對(duì)于abstractclass和

interface的選擇顯得比較隨意。其實(shí),兩者之間還是有很大的區(qū)別的,對(duì)于它

們的選擇甚至反映出對(duì)于問(wèn)題領(lǐng)域本質(zhì)的理解、對(duì)于設(shè)計(jì)意圖的理解是否正確、

合理。

AbstractclassInterface

實(shí)例

不能不能

i種繼承關(guān)系,一個(gè)類只能使用

類一次繼承關(guān)系。可以通過(guò)繼承多一>個(gè)類可以實(shí)現(xiàn)多個(gè)interface

個(gè)接口實(shí)現(xiàn)多重繼承

數(shù)據(jù)靜態(tài)的不能被修改即必須是static

可有自己的

成員final,一般不在此定義

可以私有的,非abstract方法,不可有私有的,默認(rèn)是public,abstract

方法

必須實(shí)現(xiàn)類型

可有私有的,默認(rèn)是friendly不可有私有的,默認(rèn)是publicstatic

變量型,其值可以在子類中重新定義,final型,且必須給其初值,實(shí)現(xiàn)類中不

也可以重新賦值能重新定義,不能改變其值。

設(shè)計(jì)

表示的是“is-a”關(guān)系表示的是“l(fā)ike-a”關(guān)系

理念

實(shí)現(xiàn)需要繼承,要用extends要用implements

abstractclass和interface在Java語(yǔ)言中都是用來(lái)進(jìn)行抽象類(本文中的抽

象類并非從abstractclass翻譯而來(lái),它表示的是一個(gè)抽象體,而abstract

class為Java語(yǔ)言中用于定義抽象類的一種方法)定義的,那么什么是抽象類,

使用抽象類能為我們帶來(lái)什么好處呢?

聲明方法的存在而不去實(shí)現(xiàn)它的類被叫做抽象類(abstractclass),它用于要

創(chuàng)建一個(gè)體現(xiàn)某些基本行為的類,并為該類聲明方法,但不能在該類中實(shí)現(xiàn)該類

的情況。不能創(chuàng)建abstract類的實(shí)例。然而可以創(chuàng)建一個(gè)變量,其類型是一個(gè)

抽象類,并讓它指向具體子類的一個(gè)實(shí)例。不能有抽象構(gòu)造函數(shù)或抽象靜態(tài)方法。

Abstract類的子類為它們父類中的所有抽象方法提供實(shí)現(xiàn),否則它們也是抽象

類為。取而代之,在子類中實(shí)現(xiàn)該方法。知道其行為的其它類可以在類中實(shí)現(xiàn)這

些方法。

接口(interface)是抽象類的變體。在接口中,所有方法都是抽象的。多繼承

性可通過(guò)實(shí)現(xiàn)這樣的接口而獲得。接口中的所有方法都是抽象的,沒(méi)有一個(gè)有程

序體。接口只可以定義staticfinal成員變量。接口的實(shí)現(xiàn)與子類相似,除了

該實(shí)現(xiàn)類不能從接口定義中繼承行為。當(dāng)類實(shí)現(xiàn)特殊接口時(shí),它定義(即將程序

體給予)所有這種接口的方法。然后,它可以在實(shí)現(xiàn)了該接口的類的任何對(duì)象上

調(diào)用接口的方法。由于有抽象類,它允許使用接口名作為引用變量的類型。通常

的動(dòng)態(tài)聯(lián)編將生效。引用可以轉(zhuǎn)換到接口類型或從接口類型轉(zhuǎn)換,instanceof運(yùn)

算符可以用來(lái)決定某對(duì)象的類是否實(shí)現(xiàn)了接口。

接口可以繼承接口。抽象類可以實(shí)現(xiàn)(implements)接口,抽象類是可以繼承實(shí)體

類,但前提是實(shí)體類必須有明確的構(gòu)造函數(shù)。接口更關(guān)注“能實(shí)現(xiàn)什么功能”,

而不管“怎么實(shí)現(xiàn)的”。

1.相同點(diǎn)

A.兩者都是抽象類,都不能實(shí)例化。

B.interface實(shí)現(xiàn)類及abstrctclass的子類都必須要實(shí)現(xiàn)已經(jīng)聲明的抽象

方法。

2.不同點(diǎn)

A.interface需要實(shí)現(xiàn),要用implements,而abstractclass需要繼承,要

用extendso

B.一個(gè)類可以實(shí)現(xiàn)多個(gè)interface,但一個(gè)類只能繼承一個(gè)abstractclass。

C.interface強(qiáng)調(diào)特定功能的實(shí)現(xiàn),而abstractclass強(qiáng)調(diào)所屬關(guān)系。

D.盡管interface實(shí)現(xiàn)類及abstrctclass的子類都必須要實(shí)現(xiàn)相應(yīng)的抽象

方法,但實(shí)現(xiàn)的形式不同。interface中的每一個(gè)方法都是抽象方法,都只是聲

明的(declaration,沒(méi)有方法體),實(shí)現(xiàn)類必須要實(shí)現(xiàn)。而abstractclass的子

類可以有選擇地實(shí)現(xiàn)。

這個(gè)選擇有兩點(diǎn)含義:

一是Abastractclass中并非所有的方法都是抽象的,只有那些冠有

abstract的方法才是抽象的,子類必須實(shí)現(xiàn)。那些沒(méi)有abstract的方法,在

Abstrctclass中必須定義方法體。

二是abstractclass的子類在繼承它時(shí),對(duì)非抽象方法既可以直接繼承,

也可以覆蓋;而對(duì)抽象方法,可以選擇實(shí)現(xiàn),也可以通過(guò)再次聲明其方法為抽象

的方式,無(wú)需實(shí)現(xiàn),留給其子類來(lái)實(shí)現(xiàn),但此類必須也聲明為抽象類。既是抽象

類,當(dāng)然也不能實(shí)例化。

E.abstractclass是interface與Class的中介。

interface是完全抽象的,只能聲明方法,而且只能聲明pulic的方法,不能

聲明private及protected的方法,不能定義方法體,也不能聲明實(shí)例變量。然

而,interface卻可以聲明常量變量,并且在JDK中不難找出這種例子。但將常

量變量放在interface中違背了其作為接口的作用而存在的宗旨,也混淆了

interface與類的不同價(jià)值。如果的確需要,可以將其放在相應(yīng)的abstractclass

或Class中o

abstractclass在interface及Class中起到了承上啟下的作用。一方面,

abstractclass是抽象的,可一以聲明抽象方法,以規(guī)范子類必須實(shí)現(xiàn)的功能;

另一方面,它又可以定義缺省的方法體,供子類直接使用或覆蓋。另外,它還可

以定義自己的實(shí)例變量,以供子類通過(guò)繼承來(lái)使用。

3.interface的應(yīng)用場(chǎng)合

A.類與類之前需要特定的接口進(jìn)行協(xié)調(diào),而不在乎其如何實(shí)現(xiàn)。

B.作為能夠?qū)崿F(xiàn)特定功能的標(biāo)識(shí)存在,也可以是什么接口方法都沒(méi)有的純粹

標(biāo)識(shí)。

C.需要將一組類視為單一的類,而調(diào)用者只通過(guò)接口來(lái)與這組類發(fā)生聯(lián)系。

D.需要實(shí)現(xiàn)特定的多項(xiàng)功能,而這些功能之間可能完全沒(méi)有任何聯(lián)系。

4.abstractclass的應(yīng)用場(chǎng)合

一句話,在既需要統(tǒng)一的接口,又需要實(shí)例變量或缺省的方法的情況下,就可

以使用它。最常見(jiàn)的有:

A.定義了一組接口,但又不想強(qiáng)迫每個(gè)實(shí)現(xiàn)類都必須實(shí)現(xiàn)所有的接口??梢?/p>

用abstractclass定義一組方法體,甚至可以是空方法體,然后由子類選擇自

己所感興趣的方法來(lái)覆蓋。

B.某些場(chǎng)合下,只靠純粹的接口不能滿足類與類之間的協(xié)調(diào),還必需類中表

示狀態(tài)的變量來(lái)區(qū)別不同的關(guān)系。abstract的中介作用可以很好地滿足這一點(diǎn)。

C.規(guī)范了一組相互協(xié)調(diào)的方法,其中一些方法是共同的,與狀態(tài)無(wú)關(guān)的,可

以共享的,無(wú)需子類分別實(shí)現(xiàn);而另一些方法卻需要各個(gè)子類根據(jù)自己特定的狀

態(tài)來(lái)實(shí)現(xiàn)特定的功能。

Public,Private,Protected?default?

方法的訪問(wèn)控制

訪問(wèn)說(shuō)

不同、、、即符publicprotecteddefaultprivate

情形下、'、、、

同類////

同包///

_______________S__

子類//

通用性/

==、equals的區(qū)別?

equals方法(是String類從它的超類Object中繼承的)被用來(lái)檢測(cè)兩個(gè)對(duì)象是否相等,即

兩個(gè)對(duì)象的內(nèi)容是否相等。

==用于比較引用和比較基本數(shù)據(jù)類型時(shí)具有不同的功能:

比較基本數(shù)據(jù)類型,如果兩個(gè)值相同,則結(jié)果為true

而在比較引用時(shí),如果引用指向內(nèi)存中的同一對(duì)象,結(jié)果為true

Eg:sl=newString("sony");〃創(chuàng)建的是字符串對(duì)象

sl.equals("sony");〃返回

truesl=="sony"〃返回false

〃如果

si="sony";

si=="sony"〃返回true

常用的JAVA集合及異同

集合指多個(gè)元素的聚集體。JavaCollectionsFramework是Java提供的對(duì)集合進(jìn)行

定義,操作,和管理的包含一組接口,類的體系結(jié)構(gòu)。本文對(duì)JavaCollectionsFramework

的體系結(jié)構(gòu)作一個(gè)全面深入的介紹。

Java集合框架的基本接口/類層次結(jié)構(gòu):

java.util.Collection[I]

+-java.util.List[I]

+一java.util.ArrayList[C]

+-java.util.LinkedList[C]

+一java.util.Vector[C]

+-java.util.Stack

+-java.util.Set[I]

+-java.util.HashSet[C]

+--java.util.SortedSet[I]

+-java.util.TreeSet[C]

java.util.Map

+-java.util.SortedMap[I]

+--java.util.TreeMap[C]

+-java.util.Hashtable[C]

+--java.util.HashMap[C]

+--java.util.LinkedHashMap[C]

+--java.util.WeakHashMap[C]

[I]:接口

[C]:類

Collection集合

Collection是最基本的集合接口,一個(gè)Collection代表一組Object的集合,這些Objcct

被稱作Collection的元素。

根據(jù)用途的不同,Collection又劃分為L(zhǎng)ist與Set。

Collection接口的主要接口方法有:

viewplaincopytoclipboardprint?

publicinterfaceCollection

extendsIterable

〃取得Collection的容量(元素?cái)?shù)目)

publicabstractintsize();

〃判斷是否為空

publicabstractbooleanisEmpty();

〃判斷是否包含某對(duì)象元素

publicabstractbooleancontains(Objectobj);

〃取得對(duì)所有元素的遍歷。可以通過(guò)Iterator提供的方法遍歷集合的元素

publicabstractIteratoriterator();

〃將集合元素以數(shù)據(jù)形式返回

publicabstractObject[]toArray();

publicabstractObject[]toArray(Objectaobj[]);

〃向集合體插入?個(gè)新的元素

publicabstractbooleanadd(Objectobj);

〃從集合體刪除一個(gè)元素

publicabstractbooleanremove(Objectobj);

〃是否包含所有collection里的所有元素

publicabstractbooleancontainsAII(Collectioncollection);

〃插入collection里的所有元素

publicabstractbooleanaddAII(Collectioncollection);

〃移除collection里的所有元素

publicabstractbooleanremoveAII(Collectioncollection);

publicabstractbooleanretainAII(Collectioncollection);

〃移除所有元素

publicabstractvoidclear();

//...othermethods

)

該接口定義了集合的基本操作方法。

List集合

List繼承自Collection接口。List是一種有序集合,List中的元素可以根據(jù)索引(順序

號(hào):元素在集合中處于的位置信息)進(jìn)行取得/刪除/插入操作。

跟Set集合不同的是,List允許有重復(fù)元素。對(duì)于滿足el.equals(e2)條件的el與e2對(duì)象

元素,可以同時(shí)存在于List集合中。當(dāng)然,也有List的實(shí)現(xiàn)類不允許重復(fù)元素的存在.

同時(shí),List還提供—t'listiterator()方法,返回一個(gè)Listiterator接口對(duì)象,和Iterator

接口相比,Listiterator添加元素的添加,刪除,和設(shè)定等方法,還能向前或向后遍歷。

List接口添加的主要方法有:

viewplaincopytoclipboardprint?

publicinterfaceList

extendsCollection

(

//...otherCollectionmethods

〃根據(jù)索引取得元素

publicabstractObjectget(inti);

〃在指定位置(索引)處插入新的元素

publicabstractObjectset(inti,Objectobj);

〃在List的尾部插入新的元素

publicabstractvoidadd(inti,Objectobj);

〃刪除指定位置(索引)處的元素

publicabstractObjectremove(inti);

〃取得指定對(duì)象的最開(kāi)始的索引位置

publicabstractintindexOf(Objectobj);

〃取得指定對(duì)象的最后的索引位置

publicabstractintlastlndexOf(Objectobj);

//List提供的新的遍歷方法

publicabstractListiteratorlistlterator();

〃從指定位置i處開(kāi)始迭代。最初next。方法返回的將是位置i處的元素。

publicabstractListiteratorlistlterator(inti);

〃取得從位置i到j(luò)的所有元素(包含i但不包含j位置的元素),返回一個(gè)新的集合對(duì)象。

publicabstractListsubList(inti,intj);

Set集合

Set繼承自Collection接口。Set是一種不能包含有重復(fù)元素的集合,即對(duì)于滿足

el.equals(e2)條件的el與e2對(duì)象元素,不能同時(shí)存在于同一個(gè)Set集合里,換句話說(shuō),

Set集合里任意兩個(gè)元素el和e2都滿足el.equals(e2)==false條件,Set最多有一-個(gè)null

元素。

因?yàn)镾et的這個(gè)制約,在使用Set集合的時(shí)候,應(yīng)該注意:

1,為Set集合里的元素的實(shí)現(xiàn)類實(shí)現(xiàn)一個(gè)有效的equals(Object)方法。

2,對(duì)Set的構(gòu)造函數(shù),傳入的Collection參數(shù)不能包含重復(fù)的元素。

Set接口里定義的方法與Collection基本?樣,這里不再重述。

Map集合

Map沒(méi)有繼承Collection接口。也就是說(shuō)Map和Collection是2種不同的集合。Collection

可以看作是(value)的集合,而Map可以看作是(key,value)的集合。

Map接口山Map的內(nèi)容提供3種類型的集合視圖,,組key集合,■■組value集合,或者?,

組key-value映射關(guān)系的集合

Map接口

viewplaincopytoclipboardprint?

publicinterfaceMap

(

//

publicstaticinterfaceEntry

(

publicabstractObjectgetKeyf);

publicabstractObjectgetValue();

publicabstractObjectsetValue(Objectobj);

〃…

)

〃作用基本等同Collection接口的方法

publicabstractintsize();

publicabstractbooleanisEmpty();

publicabstractbooleancontainsKey(Objectobj);

publicabstractbooleancontainsValue(Objectobj);

publicabstractObjectget(Objectobj);

publicabstractObjectput(Objectobj,Objectobjl);

publicabstractObjectremove(Objectobj);

publicabstractvoidclear();

〃添加map里包含的所有元素

publicabstractvoidputAII(Mapmap);

〃key集合

publicabstractSetkeySet();

//value集合

publicabstractCollectionvalues();

//key-value映射關(guān)系的集合Set<Entry>

publicabstractSetentrySet();

//...

集合的遍歷:

所有java.util.Collection的實(shí)現(xiàn)類必須實(shí)現(xiàn)

publicabstractIteratoriterator();

方法以支持對(duì)所包含的對(duì)象進(jìn)行遍歷。

java.util.Iterator[I]

十一一java.util.Listiterator[I]

Iterator接口:

viewplaincopytoclipboardprint?

publicinterfaceIterator

(

〃判斷是否存在下一個(gè)元素

publicabstractbooleanhasNext();

〃返回下一個(gè)可用的元素

publicabstractObjectnext();

〃移除當(dāng)前元素

publicabstractvoidremove();

Listiterator接口:

viewplaincopytoclipboardprint?

publicinterfaceListiterator

extendsIterator

(

//othermethodsdefinedinIterator

〃判斷是否存在上一個(gè)元素

publicabstractbooleanhasPrevious();

〃返回上一個(gè)可用的元素

publicabstractObjectprevious();

〃取得下一個(gè)可用元素的索引位置

publicabstractintnextlndex();

〃取得上一個(gè)可用元素的索引位置

publicabstractintpreviouslndex();

〃替換當(dāng)前位置的元素

publicabstractvoidset(Objectobj);

〃在當(dāng)前位置插入新元素

publicabstractvoidadd(Objectobj);

對(duì)集合操作的工具類

Java提供了java.util.Collections,以及java.util.Arrays類簡(jiǎn)化對(duì)集合的操作

java.util.Collections主要提供一些static方法用來(lái)操作或創(chuàng)建Collection,Map等集

合。

java.util.Arrays主要提供static方法對(duì)數(shù)組進(jìn)行操作。

ArrayList與LinkedList等的性能比較

JavaCollectionsFramework的List集合類主要有ArrayList,LinkedList,Vector,Stack

等。本文主要對(duì)它們作一個(gè)比較,說(shuō)明它們的異同點(diǎn)以及性能上的區(qū)別等。

概要

我們?cè)贘avaCollectionsFramework-Java集合框架List,Map,Set等全面介紹之概要

篇一文中對(duì)Java集合框架(JavaCollectionsFramework)做了一個(gè)比較全面的介紹。

該文粗略地介紹了List集合的概念定義等。

List集合

List繼承自Collection接口。List是一種有序集合,List中的元素可以根據(jù)索引(順序

號(hào):元素在集合中處于的位置信息)進(jìn)行取得/刪除/插入操作。

跟Set集合不同的是,List允許有重復(fù)元素。對(duì)于滿足el.equals(e2)條件的el與e2對(duì)象

元素,可以同時(shí)存在于List集合中。當(dāng)然,也有List的實(shí)現(xiàn)類不允許重復(fù)元素的存在。

同時(shí),List還提供一個(gè)listiterator()方法,返回一個(gè)ListIterator接口對(duì)象,和Iterator

接口相比,Listiterator添加元素的添加,刪除,和設(shè)定等方法,還能向前或向后遍歷。

List跟Collection的關(guān)系:

java.util.Collection[I]

+一一java.util.List[I]

+-java.util.ArrayList[C]

+--java.util.LinkedList[C]

+一java.util.Vector[C]

+--java.util.Stack[C]

List接口的實(shí)現(xiàn)類主要有ArrayList,LinkedList,Vector,Stack等。

本文主要對(duì)上面提到的幾個(gè)類作一個(gè)比較,說(shuō)明它們的異同點(diǎn)以及性能上的區(qū)別等。

ArrayList,LinkedList,Vector,Stack的相同點(diǎn)

ArrayList,LinkedList,Vector,Stack等類都實(shí)現(xiàn)了List接口,都屬于List集合。

List接口里定義的基本方法是一樣的。

publicinterfaceList

extendsCollection

(

//...otherCollectionmethods

〃根據(jù)索引取得元素

publicabstractObjectget(inti);

〃在指定位置(索引)處插入新的元素

publicabstractObjectset(inti,Objectobj);

〃在List的尾部插入新的元素

publicabstractvoidadd(inti,Objectobj);

〃刪除指定位置(索引)處的元素

publicabstractObjectremove(inti);

〃取得指定對(duì)象的最開(kāi)始的索引位置

publicabstractintindexOf(Objectobj);

〃取得指定對(duì)象的最后的索引位置

publicabstractintlastlndexOf(Objectobj);

//List提供的新的遍歷方法

publicabstractListiteratorlistiterator();

〃從指定位置i處開(kāi)始迭代。最初next()方法返回的將是位置i處的元素。

publicabstractListiteratorlistiterator(inti);

〃取得從位置i到j(luò)的所有元素(包含i但不包含j位置的元素),返回一個(gè)新的集合

對(duì)象。

publicabstractListsubList(inti,intj);

)

ArrayList,LinkedList,Vector,Stack的相異之處:

數(shù)據(jù)構(gòu)造上的差異:

ArrayList,Vector,Stack都是使用動(dòng)態(tài)數(shù)組來(lái)保存集合中的對(duì)象元素,亦即ArrayList,

Vector,Stack具有基本相似的數(shù)據(jù)結(jié)構(gòu)。ArrayList,Vector除了以下所說(shuō)的線程同步上

的差異之外,它們的功能基本一樣;Vector從Stack繼承,除了擁有Stack具有的功能之

外,還實(shí)現(xiàn)了棧的功能。

而LinkedList則使用鏈表的形式來(lái)保存集合中的對(duì)象元素。

線程處理上的差異:

ArrayList,LinkedList沒(méi)有使用synchronized對(duì)線程同步作任何處理,也就是說(shuō)它們?cè)?/p>

同一時(shí)刻可以由多個(gè)線程訪問(wèn),不是線程安全的;

Vector,Stack則使用synchronized對(duì)主要方法作了同步控制,它們?cè)谕粫r(shí)刻只能由一

個(gè)線程訪問(wèn)。

ArrayList.LinkedList,Vector,Stack的性能比較:

因?yàn)閿?shù)據(jù)構(gòu)造上的差異,它們?cè)谔幚碓氐奶砑?,刪除,插入,索引取值,遍歷取值方面的

效率上也各不相同。

ArrayList,Vector,Stack都是采用動(dòng)態(tài)數(shù)組,它們的處理效率基本一樣。

LinkedList采用鏈表構(gòu)造,所以它跟ArrayList,Vector,Stack在添加,刪除,插入,取

值操作上就很大差異。

在具體的應(yīng)用中,為了性能,功能上的考慮,我們可以根據(jù)具體的需求采用不同的List。

ArrayList,Vector,Stack

元素添加操作

ArrayList,Vector,Stack添加元素時(shí)的基本步驟是:

-確保動(dòng)態(tài)數(shù)組的空間大小。若空間不夠時(shí),則為集合元素重新分配空間,新分配的空間是

原有空間大小的L5倍左右,并把原來(lái)的集合元素拷貝到新分配的空間上。所以如果對(duì)象元

素很多,有可能分配的空間大小要遠(yuǎn)遠(yuǎn)多出實(shí)際的元素,所以為了內(nèi)存利用效率考慮,使用

ArrayList等時(shí),如果事先知道元素的多少,最好初始化時(shí)為其分配最大空間。

-設(shè)置新元素到size+l位置。

大量添加時(shí)的性能:因?yàn)橹匦路峙淇臻g的次數(shù)不會(huì)太多,性能評(píng)價(jià):好

元素刪除操作

-將刪除位置i以后的元素全部往前移一個(gè)位置

-設(shè)置size處元素為null

大量刪除時(shí)的性能:因?yàn)槊總€(gè)元素的刪除都會(huì)進(jìn)行移位拷貝,性能評(píng)價(jià):差

元素插入操作

-同元素添加操作

-將插入位置i及以后的所有元素往后移一個(gè)位置

-設(shè)置新元素至插入位置i

大量插入時(shí)的性能:因?yàn)槊總€(gè)元素的插入都會(huì)進(jìn)行移位拷貝,性能評(píng)價(jià):差

索引取值/遍歷取值

因?yàn)槭莿?dòng)態(tài)數(shù)組結(jié)構(gòu),所以索引取值(根據(jù)數(shù)組的下標(biāo))的速度非???。

它們的遍歷取值(Iterator,next())的內(nèi)部實(shí)現(xiàn)是根據(jù)當(dāng)前元素的位置取得下一個(gè)元素,

所以跟索引取值一樣,都是簡(jiǎn)單地引用數(shù)組的下標(biāo),所以速度也非常快。

性能評(píng)價(jià):極優(yōu)

LinkedList

元素添加操作

元素刪除操作

元素插入操作

LinkedList的元素添加,刪除,插入的操作步驟一樣:

-定位需要操作的元素

-執(zhí)行添加,刪除,插入操作

雖然在元素的定位操作上需要花些時(shí)間,但LinkedList在處理時(shí)對(duì)元素的定位作了優(yōu)化,

性能評(píng)價(jià):好

索引取值

因?yàn)長(zhǎng)inkedList的鏈表結(jié)構(gòu),所以對(duì)元素的索引取值是一個(gè)遍歷的過(guò)程,性能評(píng)價(jià):極差

遍歷取值

LinkedList在遍歷的時(shí)候保存了當(dāng)前元素,因?yàn)樗逆湵斫Y(jié)構(gòu),可以快速的定位下一個(gè)元

素。性能評(píng)價(jià):極優(yōu)

性能總結(jié):

一人itera

add()操delete()操insert操index取值

tor取值

作作作操作

操作

ArrayList/Vector/好差差極極

Stack優(yōu)優(yōu)

好好好差極

LinkedList

優(yōu)

下面舉例來(lái)說(shuō)明它們?cè)谛阅苌系膮^(qū)別。

代碼

viewplaincopytoclipboardprint?

packagecom.test.collection;

importjava.util.Iterator;

importjava.util.List;

publicclassTestList{

/**

*List集合性能測(cè)試類

*Usage:javacom.test.collection.TestListListClassNameMAX_TIMES

*例:javacom.test.collection.TestListLinkedList100000

*/

publicstaticvoidmain(String[]args){

if(args!=null&&args.length==2){

testList(args[O],Integer.parselnt(args[l]));

}else{

testList("LinkedList",20000);

testList("ArrayList",20000);

)

)

privatestaticvoidtestList(StringlistName,intmaxElements){

Listlist=null;

try(

list=(List)Class.forName("java.util."+listName).newlnstance();

}catch(Exceptione){

e.printStackTrace();

)

addElement2List(list,maxElements);

deleteElement2List(list);

insertElement2List(list/maxements);

getListElementBylndex(list);

getList日ementBylterator(list);

)

//addelementstoList

privatestaticvoidadd日ement2List(Listlist,intmax日ements){

longstart=System.currentTimeMillis();

for(inti=1;i<maxElements;i++){

list.add(newInteger(i));

}

longend=System.currentTimeMillis();

printTime(list,end-start,"[add]H);

//removeelementsfromList

privatestaticvoiddelete日ement2List(Listlist){

longstart=System.currentTimeMillis();

while(!list.isEmpty()){

list.remove(O);

)

longend=System.currentTimeMillis();

printTime(list,end-start,"[delete]");

//insertelementstoList

privatestaticvoidinsert日ement2List(Listlist,intmaxElements){

longstart=System.currentTimeMillis();

for(inti=1;i<maxElements;i++){

list.add(O,newInteger(i));

)

longend=System.currentTimeMillis();

printTime(list,end-start,n[insert]");

)

privatestaticvoidgetListElementBylndex(Listlist){

longstart=System.currentTimeMillis();

for(inti=1;i<list.size();i++){

Integerele=(Integer)list.get(i);

)

longend=System.currentTimeMillis();

printTime(list,end-start,"[index]");

)

privatestaticvoidgetListElementBylterator(Listlist){

longstart=System.currentTimeMillis();

Iteratorite=list.iterator();

while(ite.hasNext()){

Integerele=(lnteger)ite.next();

)

longend=System.currentTimeMillis();

printTime(list/end-start,"[iterator]");

)

privatestaticvoidprintTime(Listlist,longtime,Stringoperation){

Stringout=list.getClass().getSimpleName();

out+=""+operation+"+time;

System.out.println(out);

執(zhí)行Client,輸出結(jié)果:

C:\test\list>javacom.test,collection.TestListArrayList100000

ArrayList[add]:79

ArrayList[delete]:8703

ArrayList[insert]:9281

ArrayList[index]:0

ArrayList[iterator]:16

C:\test\list>javacom.test.collection.TestListLinkedList100000

LinkedList[add]:125

LinkedList[delete]:16

LinkedList[insert]:78

LinkedList[index]:80328

LinkedList[iterator]:0

C:\test\list>javacom.test,collection.TestListVector100000

Vector[add]:63

Vector[delete]:8546

Vector[insert]:9422

Vector[index]:16

Vector[iterator]:0

C:\test\list>javacom.test,collection.TestListStack100000

Stack[add]:47

Stack[delete]:8593

Stack[insert]:9610

Stack[index]:0

Stack[iterator]:16

總結(jié):

本文主要比較了ArrayList,Vector,Stack與LinkedList的操作性能。

ArrayList,Vector與Stack在索引取值,迭代取值上有較高的性能。

LinkedList在刪除,插入,迭代取值上有較高的性能。

JAVA集合類(大公司面試喜歡問(wèn)的)

看了一些所謂大公司的JAVA面試問(wèn)題,發(fā)現(xiàn)對(duì)于JAVA集合類的使用都比較看重似的,而自

己在這方面還真的是所真甚少,抽空也學(xué)習(xí)學(xué)習(xí)吧。

java.util包中就包含了一系列重要的集合類,而對(duì)于集合類,主要需要掌握的就是它的內(nèi)部

結(jié)構(gòu),以及遍歷集合的迭代模式。

接口:Collection

所有集合類的根類型,主要的一個(gè)接口方法:booleanadd(Ojbectc)

雖返回的是boolean,但不是表示添加成功與否,因?yàn)镃ollection規(guī)定:一個(gè)集合拒絕添加

這個(gè)元素,無(wú)論什么原因,都必須拋出異常,這個(gè)返回值表示的意義是add()執(zhí)行后,集合

的內(nèi)容是否改了(就是元素有無(wú)數(shù)量、位置等變化)。類似的addAII,remove,removeAIL

remainAII也是一樣的。

用Iterator模式實(shí)現(xiàn)遍歷集合

Collection有一個(gè)重要的方法:iterator。,返回一個(gè)Iterator(迭代子),用于遍歷集合的所有

元素。Iterator模式可以把訪問(wèn)邏輯從不同類的集合類中抽象出來(lái),從而避免向客戶端暴露

集合的內(nèi)部結(jié)構(gòu)。

for(Iteratorit=c.iterator();it.hasNext();){...}

不需要維護(hù)遍歷集合的“指針”,所有的內(nèi)部狀態(tài)都有Iterator來(lái)維護(hù),而這個(gè)Iterator山集

合類通過(guò)工廠方法生成。

每一種集合類返回的Iterator具體類型可能不同,但它們都實(shí)現(xiàn)了Iterator接口,因此,我

們不需要關(guān)心到底是哪種Iterator,它只需要獲得這個(gè)Iterator接口即可,這就是接口的好處,

面向?qū)ο蟮耐Α?/p>

要確保遍歷過(guò)程順利完成,必須保證遍歷過(guò)程中不更改集合的內(nèi)容(Iterator的remove。方

法除外),所以,確保遍歷可靠的原則是:只在一個(gè)線程中使用這個(gè)集合,或者在多線程中

對(duì)遍歷代碼進(jìn)行同步。

JAVAM叩集合類介紹

直接貼鏈接好了

/article/54/54534.shtm

線性表,鏈表,哈希表是常用的數(shù)據(jù)結(jié)構(gòu),在進(jìn)行Java開(kāi)發(fā)時(shí),JDK已經(jīng)為我們提供了一系

列相應(yīng)的類來(lái)實(shí)現(xiàn)基本的數(shù)據(jù)結(jié)構(gòu)。這些類均在java.util包中。本文試圖通過(guò)簡(jiǎn)單的描述,

向讀者闡述各個(gè)類的作用以及如何正確使用這些類。

Collection

|-List

IpLinkedList

卜ArrayList

ILVector

|LStack

LSet

Map

卜Hashtable

[-HashMap

LWeakHashMap

Collection接口

Collection是最基本的集合接口,一個(gè)Collection代表一組Object,即Collection的元素

(Elements)o一些Collection允許相同的元素而另一些不行。一些能排序而另一些不行。Java

SDK不提供直接繼承自Collection的類,JavaSDK提供的類都是繼承自Collection的“子接口”

如List和Seto

所有實(shí)現(xiàn)Collection接口的類都必須提供兩個(gè)標(biāo)準(zhǔn)的構(gòu)造函數(shù):無(wú)參數(shù)的構(gòu)造函數(shù)用于

創(chuàng)建一個(gè)空的Collection,有一個(gè)Collection參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)新的Collection,

這個(gè)新的Collection與傳入的Collection有相同的元素。后一個(gè)構(gòu)造函數(shù)允許用戶復(fù)制一個(gè)

Collectiono

如何遍歷Collection中的每一個(gè)元素?不論Collection的實(shí)際類型如何,它都支持一個(gè)

iterator。的方法,該方法返回一個(gè)迭代子,使用該迭代子即可逐一訪問(wèn)Collection中每一個(gè)

元素。典型的用法如下:

Iteratorit=collection.iterator();//獲得一個(gè)迭代子

while(it.hasNext()){

Objectobj=it.next();//得到下一個(gè)元素

)

由Collection接口派生的兩個(gè)接口是List和Seto

List接口

List是有序的Collection,使用此接口能夠精確的控制每個(gè)元素插入的位置。用戶能夠使

用索引(元素在List中的位置,類似于數(shù)組下標(biāo))來(lái)訪問(wèn)List中的元素,這類似于Java的數(shù)

組。

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

除了具有Collection接口必備的iterator。方法外,List還提供一個(gè)listlterator。方法,返

回一個(gè)Listiterator接口,和標(biāo)準(zhǔn)的Iterator接口相比,Listiterator多了?些add()之類的方法,

允許添加,刪除,設(shè)定元素,還能向前或向后遍歷。

實(shí)現(xiàn)List接口的常用類有LinkedList,ArrayList,Vector和Stack。

LinkedList類

LinkedList實(shí)現(xiàn)了List接口,允許null元素。此外LinkedList提供額外的get,remove,insert

方法在LinkedList的首部或尾部。這些操作使LinkedList可被用作堆棧(stack),隊(duì)列(queue)

或雙向隊(duì)列(deque)。

注意LinkedList沒(méi)有同步方法。如果多個(gè)線程同時(shí)訪問(wèn)個(gè)List,則必須自己實(shí)現(xiàn)訪問(wèn)

同步。一種解決方法是在創(chuàng)建List時(shí)構(gòu)造一個(gè)同步的List:

Listlist=Collections.synchronizedList(newLinkedList(…));

ArrayList類

ArrayList實(shí)現(xiàn)了可變大小的數(shù)組。它允許所有元素,包括null。ArrayList沒(méi)有同步。

size,isEmpty,get,set方法運(yùn)行時(shí)間為常數(shù)。但是add方法開(kāi)銷為分?jǐn)偟某?shù),添加n個(gè)

元素需要0(n)的時(shí)間。其他的方法運(yùn)行時(shí)間為線性。

每個(gè)ArrayList實(shí)例都有一個(gè)容量(Capacity),即用于存儲(chǔ)元素的數(shù)組的大小。這個(gè)容量

可隨著不斷添加新元素而自動(dòng)增加,但是增長(zhǎng)算法并沒(méi)有定義。當(dāng)需要插入大量元素時(shí),在

插入前可以調(diào)用ensureCapacity方法來(lái)增加ArrayList的容量以提高插入效率。

和LinkedList一樣,ArrayList也是非同步的(unsynchronized)。

Vector類

Vector非常類似ArrayList,但是Vector是同步的。由Vector創(chuàng)建的Iterator,雖然和

ArrayList創(chuàng)建的Iterator是同一接口,但是,因?yàn)閂ector是同步的,當(dāng)一個(gè)Iterator被創(chuàng)建

而且正在被使用,另一個(gè)線程改變了Vector的狀態(tài)(例如,添加或刪除了一些元素),這時(shí)

調(diào)用Iterator的方法時(shí)將拋出ConcurrentModificationException,因此必須捕獲該異常。

Stack類

Stack繼承自Vector,實(shí)現(xiàn)一個(gè)后進(jìn)先出的堆棧。Stack提供5個(gè)額外的方法使得Vector

得以被當(dāng)作堆棧使用?;镜膒ush和pop方法,還有peek方法得到棧頂?shù)脑?,empty方

法測(cè)試堆棧是否為空,search方法檢測(cè)一個(gè)元素在堆棧中的位置。Stack剛創(chuàng)建后是空棧。

Set接口

Set是一種不包含重復(fù)的元素的Collection,即任意的兩個(gè)元素el和e2都有

el.equals(e2)=false,Set最多有一個(gè)null元素。

很明顯,Set的構(gòu)造函數(shù)有一個(gè)約束條件,傳入的Collection參數(shù)不能包含重復(fù)的元素。

請(qǐng)注意:必須小心操作可變對(duì)象(MutableObject),如果-一個(gè)Set中的可變?cè)馗淖兞?/p>

自身狀態(tài)導(dǎo)致Object.equals(Object);true將導(dǎo)致一些問(wèn)題。

Map接口

請(qǐng)注意,Map沒(méi)有繼承Collection接口,Map提供key到value的映射。一個(gè)Map中不

能包含相同的key,每個(gè)key只能映射一個(gè)value。Map接口提供3種集合的視圖,Map的

內(nèi)容可以被當(dāng)作一組key集合,一組value集合,或者--組key-value映射。

Hashtable類

Hashtable繼承Map接口,實(shí)現(xiàn)一個(gè)key-value映射的哈希表。任何非空(non-null)的

對(duì)象都可作為key或者valueo

添加數(shù)據(jù)使用put(key,value),取出數(shù)據(jù)使用get(key),這兩個(gè)基本操作的時(shí)間開(kāi)銷為常

數(shù)。

Hashtable通過(guò)initialcapacity和loadfactor兩個(gè)參數(shù)調(diào)整性能。通常缺省的loadfactor0.75

較好地實(shí)現(xiàn)了時(shí)間和空間的均衡。增大loadfactor可以節(jié)省空間但相應(yīng)的查找時(shí)間將增大,

這會(huì)影響像get和put這樣的操作。

使用Hashtable的簡(jiǎn)單示例如下,將1,2,3放到Hashtable中,他們的key分別是“one",”

two","three”:

Hashtablenumbers=newHashtable();

numbers.put(“one”,newInteger(l));

numbers.put(“two”,newlnteger(2));

numbers.put("three”,newlnteger(3));

要取出一個(gè)數(shù),比如2,用相應(yīng)的key:

Integern=(lnteger)numbers.get(“two");

System.out.println(utwo="+n);

山于作為key的對(duì)象將通過(guò)計(jì)算其散列函數(shù)來(lái)確定與之對(duì)應(yīng)的value的位置,因此任何

作為key的對(duì)象都必須實(shí)現(xiàn)hashCode和equals方法。hashCode和equals方法繼承自根類

Object,如果你用自定義的類當(dāng)作key的話,要相當(dāng)小心,按照散列函數(shù)的定義,如果兩個(gè)

對(duì)象相同,即objl.equals(obj2)=true,則它們的hashCode必須相同,但如果兩個(gè)對(duì)象不同,

則它們的hashCode不一定不同,如果兩個(gè)不同對(duì)象的hashCode相同,這種現(xiàn)象稱為沖突,

沖突會(huì)導(dǎo)致操作哈希表的時(shí)間開(kāi)銷增大,所以盡量定義好的hashCode。方法,能加快哈希表

的操作。

如果相同的對(duì)象有不同的hashCode,對(duì)哈希表的操作會(huì)出現(xiàn)意想不到的結(jié)果(期待的

get方法返回null),要避免這種問(wèn)題,只需要牢記一條:要同時(shí)復(fù)寫equals方法和hashCode

方法,而不要只寫其中一個(gè)。

Hashtable是同步的。

HashMap類

HashMap和Hashtable類似,不同之處在于HashMap是非同步的,并且允許null,即

nullvalue和nullkey。,但是將HashMap視為Collection時(shí)(values。方法可返回Collection),

其迭代子操作時(shí)間開(kāi)銷和HashMap的容量成比例。因此,如果迭代操作的性能相當(dāng)重要的

話,不要將HashMap的初始化容量設(shè)得過(guò)高,或者loadfactor過(guò)低。

WeakHashMap類

WeakHashMap是一種改進(jìn)的HashMap,它對(duì)key實(shí)行“弱引用”,如果一個(gè)key不再被

外部所引用,那么該key可以被GC回收。

總結(jié)

如果涉及到堆棧,隊(duì)列等操作,應(yīng)該考慮用List,對(duì)于需要快速插入,刪除元素,應(yīng)該

使用LinkedList,如果需要快速隨機(jī)訪問(wèn)元素,應(yīng)該使用ArrayList?

如果程序在單線程環(huán)境中,或者訪問(wèn)僅僅在一個(gè)線程中進(jìn)行,考慮非同步的類,其效率

較高,如果多個(gè)線程可能同時(shí)操作一個(gè)類,應(yīng)該使用同步的類。

要特別注意對(duì)哈希表的操作,作為key的對(duì)象要正確復(fù)寫equals和hashCode方法。

盡量返回接口而非實(shí)際的類型,如返回List而非ArrayList,這樣如果以后需要將ArrayList換

成LinkedList時(shí),客戶端代碼不用改變。這就是針對(duì)抽象編程。

java.util中的集合類包含Java中某些最常用的類。最常用的集合類是List和Map。List

的具體實(shí)現(xiàn)包括ArrayList和Vector,它們是可變大小的列表,比較適合構(gòu)建、存儲(chǔ)和操作

任何類型對(duì)象的元素列表。List適用于按數(shù)值索引訪問(wèn)元素的情形。

Map提供了一個(gè)更通用的元素存儲(chǔ)方法?M叩集合類用于存儲(chǔ)元素對(duì)(稱作"鍵"和"值"),

其中每個(gè)鍵映射到?個(gè)值。從概念上而言,您可以將List看作是具有數(shù)值鍵的Map。而

實(shí)際上,除了List和Map都在定義java.util中外,兩者并沒(méi)有直接的聯(lián)系。本文將著重

介紹核心Java發(fā)行套件中附帶的Map,同時(shí)還將介紹如何采用或?qū)崿F(xiàn)更適用于您應(yīng)用程

序特定數(shù)據(jù)的專用M叩。

了解Map接口和方法

Java核心類中有很多預(yù)定義的M叩類.在介紹具體實(shí)現(xiàn)之前,我們先介紹一下Map接

口本身,以便了解所有實(shí)現(xiàn)的共同點(diǎn)。Map接口定義了四種類型的方法,每個(gè)Map都包

含這些方法。下面,我們從兩個(gè)普通的方法(表1)開(kāi)始對(duì)這些方法加以介紹。

表1:覆蓋的方法。我們將這Object的這兩個(gè)方法覆蓋,以正確比較Map對(duì)象的等價(jià)

性。

equals(Objecto)比較指定對(duì)象與此Map的等價(jià)性

hashCode()返回此Map的哈希碼

Map構(gòu)建

Map定義了幾個(gè)用于插入和刪除元素的變換方法(表2)?

表2:Map更新方法:可以更改Map內(nèi)容。

clear()從Map中刪除所有映射

remove(Objectkey)從Map中刪除鍵和關(guān)聯(lián)的值

put(Objectkey,Objectvalue)將指定值與指定鍵相關(guān)聯(lián)

clear()從Map中刪除所有映射

putAII(Mapt)將指定Map中的所有映射復(fù)制到此map

盡管您可能注意到,縱然假設(shè)忽略構(gòu)建一個(gè)需要傳遞給的的開(kāi)銷,使用

PutAII()Map

putAIIO通常也并不比使用大量的put()調(diào)用更有效率,但putAII()的存在一點(diǎn)也不稀奇。

這是因?yàn)?,putAIIO除了迭代put()所執(zhí)行的將每個(gè)鍵值對(duì)添加到Map的算法以外,還需

要迭代所傳遞的Map的元素。但應(yīng)注意,putAIIO在添加所有元素之前可以正確調(diào)整Map

的大小,因此如果您未親自調(diào)整Map的大小(我們將對(duì)此進(jìn)行簡(jiǎn)單介紹),貝IJputAII()可

能比預(yù)期的更有效。

查看Map

迭代Ma

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論