趙艷敏高級(jí)講師
從事設(shè)計(jì)行業(yè)多年,有著豐富的設(shè)計(jì)和動(dòng)畫制作經(jīng)驗(yàn)。曾參與中國(guó)電信天翼
手機(jī)網(wǎng)及天翼手機(jī)DIY等多個(gè)項(xiàng)目的設(shè)計(jì),動(dòng)畫,及As開(kāi)發(fā)。項(xiàng)目經(jīng)驗(yàn)豐富。曾在卡酷動(dòng)畫衛(wèi)視下屬公司擔(dān)任高級(jí)動(dòng)畫師一職,參與多部動(dòng)畫片的制作
。對(duì)動(dòng)畫也有較高的造詣。
精通Flash、After Effects、Photoshop、Illustrator、ActionScript
2.0/3.0、Edius、CoolEdit、Axure RP、DIV CSS等相關(guān)技術(shù)。
講課有自己的風(fēng)格,思維活躍,條理清晰講課注重細(xì)節(jié),由簡(jiǎn)入繁。本著以
學(xué)生學(xué)會(huì)為目的,更注重理論與實(shí)踐相結(jié)合。
Java工程師就業(yè)前景
Java工程師就業(yè)前景
2015年,在美國(guó)、加拿大、澳大利亞、新加坡等發(fā)達(dá)國(guó)家和中等發(fā)達(dá)國(guó)家,
JAVA軟件工程師年薪均在4—15萬(wàn)美金,而在國(guó)內(nèi),JAVA軟件工程師也有極好的工作機(jī)會(huì)和很高的薪水。
在未來(lái)5年內(nèi),合格軟件人才的需求將遠(yuǎn)大于供給。JAVA軟件工程師是目前
國(guó)際高端計(jì)算機(jī)領(lǐng)域就業(yè)薪資非常高的一類軟件工程師。
一般情況下的JAVA軟件工程師是分四個(gè)等級(jí),從軟件技術(shù)員到助理軟件工程
師,再到軟件工程師,**后成為高級(jí)軟件工程師。
根據(jù)IDC的統(tǒng)計(jì)數(shù)字,在所有軟件開(kāi)發(fā)類人才的需求中,對(duì)JAVA工程師的需
求達(dá)到全部需求量的60%—70%。同時(shí),JAVA軟件工程師的工資待遇相對(duì)較高。
通常來(lái)說(shuō),具有3—5年開(kāi)發(fā)經(jīng)驗(yàn)的工程師,擁有年薪15萬(wàn)元是很正常的一個(gè)
薪酬水平。80%的學(xué)生畢業(yè)后年薪都超過(guò)了8萬(wàn)元。
根據(jù)專業(yè)數(shù)據(jù)分析,由于我國(guó)經(jīng)濟(jì)發(fā)展不均衡因素,JAVA軟件工程師工資待
遇在城市之間的差異也較大,一級(jí)城市(如北京、上海等),初級(jí)軟件工程師的待遇大概在4000-6000之間,中級(jí)軟件工程師的待遇在6000—8000之間,
而高級(jí)軟件工程師的待遇基本破萬(wàn)。
數(shù)據(jù)庫(kù)關(guān)鍵技術(shù)
.數(shù)據(jù)庫(kù)關(guān)鍵技術(shù)
-
01Mysql 基礎(chǔ)
-
02SQL基礎(chǔ)
-
1.SQL語(yǔ)句的三種類型
-
2.DML、DDL、DCL的應(yīng)用
-
3.數(shù)據(jù)處理
-
4.子查詢
-
5.創(chuàng)建和管理表
-
6.約束與分頁(yè)
-
03JDBC
-
04DBUtils
-
1.使用QueryRunner
-
2.可插拔式結(jié)果集處理
-
3.批量處理
-
4.大數(shù)據(jù)結(jié)果集處理
-
5.自定義結(jié)果集處理
-
6.利用DBUtils編寫通用 DAO
Collection,List,Set和Map用法和區(qū)別
>
以下內(nèi)容轉(zhuǎn)自:http://blog.csdn.net/an341221/article/details/50514664
Collection,List,Set和Map用法和區(qū)別
作者:zccst
java sPRing MVC框架的調(diào)用關(guān)系是弄明白了,可是發(fā)現(xiàn)后面要走的路還很長(zhǎng),有很多東西對(duì)我還是很神秘,比如list,set,map等,今天就來(lái)一一解開(kāi)他們的面紗。當(dāng)還還有一大堆需要記憶的系統(tǒng)已經(jīng)封裝好的類、接口等等,這些內(nèi)容會(huì)在以后,慢慢道來(lái)。
首先看一下他們之間的關(guān)系
Collection 接口的接口 對(duì)象的集合
├List 子接口 按進(jìn)入先后有序保存 可重復(fù)
│├LinkedList 接口實(shí)現(xiàn)類 鏈表 插入刪除 沒(méi)有同步 線程不安全
│├ArrayList 接口實(shí)現(xiàn)類 數(shù)組 隨機(jī)訪問(wèn) 沒(méi)有同步 線程不安全
│└Vector 接口實(shí)現(xiàn)類 數(shù)組 同步 線程安全
│ └Stack
└Set 子接口 僅接收一次,并做內(nèi)部排序
├HashSet
│ └LinkedHashSet
└TreeSet
對(duì)于List,關(guān)心的是順序,它保證維護(hù)元素特定的順序(允許有相同元素),使用此接口能夠精確的控制每個(gè)元素插入的位置。用戶能夠使用索引(元素在List中的位置,類似于數(shù)組下標(biāo))來(lái)訪問(wèn)List中的元素。
對(duì)于Set,只關(guān)心某元素是否屬于Set(不允許有相同元素),而不關(guān)心它的順序。
Map 接口 鍵值對(duì)的集合
├Hashtable 接口實(shí)現(xiàn)類 同步 線程安全
├HashMap 接口實(shí)現(xiàn)類 沒(méi)有同步 線程不安全
│├LinkedHashMap
│└WeakHashMap
├TreeMap
└IdentifyHashMap
對(duì)于Map,**大的特點(diǎn)是鍵值映射,且為一一映射,鍵不能重復(fù),值可以,所以是用鍵來(lái)索引值。方法put(Objectkey, Object value)添加一個(gè)“值”(想要得東西)和與“值”相關(guān)聯(lián)的“鍵”(key) (使用它來(lái)查找)。方法get(Object key)返回與給定“鍵”相關(guān)聯(lián)的“值”。
Map同樣對(duì)每個(gè)元素保存一份,但這是基于"鍵"的,Map也有內(nèi)置的排序,因而不關(guān)心元素添加的順序。如果添加元素的順序?qū)δ愫苤匾瑧?yīng)該使用 LinkedHashSet或者LinkedHashMap.
對(duì)于效率,Map由于采用了哈希散列,查找元素時(shí)明顯比ArrayList快。
但我有一個(gè)自己的原則想法:復(fù)雜的問(wèn)題簡(jiǎn)單化。即把很多晦澀難懂的問(wèn)題用通俗直白的話,一下子就看明白了,而不是大段大段的寫。不得不指出的是現(xiàn)在部分所謂的“專家”往往把簡(jiǎn)單的問(wèn)題復(fù)雜化,讓人看了生畏,甚至望而卻步,以此來(lái)顯示他的高深莫測(cè),當(dāng)然也可能有別的用意,那我就不得而知了。
更為精煉的總結(jié):
Collection是對(duì)象集合,Collection有兩個(gè)子接口List和Set
List可以**下標(biāo)(1,2..)來(lái)取得值,值可以重復(fù)
而Set只能**游標(biāo)來(lái)取值,并且值是不能重復(fù)的
ArrayList,Vector,LinkedList是List的實(shí)現(xiàn)類
ArrayList是線程不安全的,Vector是線程安全的,這兩個(gè)類底層都是由數(shù)組實(shí)現(xiàn)的
LinkedList是線程不安全的,底層是由鏈表實(shí)現(xiàn)的
Map是鍵值對(duì)集合
HashTable和HashMap是Map的實(shí)現(xiàn)類
HashTable是線程安全的,不能存儲(chǔ)null值
HashMap不是線程安全的,可以存儲(chǔ)null值
所以,如果你是想在一個(gè)很短的時(shí)間來(lái)弄明白這些問(wèn)題,比如1~2分鐘。沒(méi)有也不想花大量時(shí)間于此,那么建議你現(xiàn)在就可以收兵走人了。
如果你想對(duì)此做一個(gè)詳細(xì)的了解,請(qǐng)繼續(xù)看下去。
眾所周知,Java來(lái)源于C ,屏蔽了其底層實(shí)現(xiàn),簡(jiǎn)化了對(duì)底層實(shí)現(xiàn)的管理,使開(kāi)發(fā)者專注于上層功能的實(shí)現(xiàn)。在C/C 里關(guān)于數(shù)據(jù)的存儲(chǔ)需要程序員非常清楚,而Java程序員可以完全不管這些,那么,Java是怎么管理的呢?其實(shí)Java還是需要面臨這些問(wèn)題,只不過(guò)經(jīng)過(guò)封裝后,變得面目全非。所以對(duì)于像我這種從C/C 轉(zhuǎn)向Java的人還需要一段時(shí)間適應(yīng),Collection、List、Set、Map等概念還需要一個(gè)接受的過(guò)程。其實(shí)到后來(lái)發(fā)現(xiàn),不管是什么語(yǔ)言,其底層存儲(chǔ)不外乎數(shù)組、線性表、棧、隊(duì)列、串、樹(shù)和圖等數(shù)據(jù)結(jié)構(gòu)。想明白了這些,一切都敞亮了。
一、容器(Collection)接口 容器(Collection)是**基本的集合接口,一個(gè)容器(Collection)保存一組對(duì)象(Object),即對(duì)象是容器的元素(Elements)。一些 Collection允許相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接繼承自Collection的類,Java SDK提供的類都是繼承自Collection的“子接口”如List和Set。
所有實(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è)Collection。
如何遍歷Collection中的每一個(gè)元素?不論Collection的實(shí)際類型如何,它都支持一個(gè)iterator()的方法,該方法返回一個(gè)迭代子,使用該迭代子即可逐一訪問(wèn)Collection中每一個(gè)元素。典型的用法如下:
Iterator it = collection.iterator(); // 獲得一個(gè)迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一個(gè)元素
}
由Collection接口派生的兩個(gè)接口是List和Set。List按對(duì)象進(jìn)入的順序保存對(duì)象,不做排序或編輯操作。Set對(duì)每個(gè)對(duì)象只接受一次,并使用自己內(nèi)部的排序方法(通常,你只關(guān)心某個(gè)元素是否屬于Set,而不關(guān)心它的順序--否則應(yīng)該使用List)。
1,List接口 List是有序的Collection,次序是List**重要的特點(diǎn):它保證維護(hù)元素特定的順序。使用此接口能夠精確的控制每個(gè)元素插入的位置。用戶能夠使用索引(元素在List中的位置,類似于數(shù)組下標(biāo))來(lái)訪問(wèn)List中的元素,這類似于Java的數(shù)組。和下面要提到的Set不同,List允許有相同的元素。
除了具有Collection接口必備的iterator()方法外,List還提供一個(gè)listIterator()方法,返回一個(gè)ListIterator接口,和標(biāo)準(zhǔn)的Iterator接口相比,ListIterator多了一些add()之類的方法,允許添加,刪除,設(shè)定元素,還能向前或向后遍歷。
實(shí)現(xiàn)List接口的常用類有LinkedList,ArrayList,Vector和Stack。其中,**常用的是LinkedList和 ArrayList兩個(gè)。 LinkedList類 LinkedList實(shí)現(xiàn)了List接口,允許null元素。此外LinkedList提供額外的addFirst(),addLast(), getFirst(), getLast(), removeFirst(), removeLast(), insertFirst(),insertLast()方法在 LinkedList的首部或尾部,這些方法(沒(méi)有在任何接口或基類中定義過(guò))使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:
List list = Collections.synchronizedList(new LinkedList(...));
特點(diǎn):對(duì)順序訪問(wèn)進(jìn)行了優(yōu)化,向List中間插入與刪除的開(kāi)銷并不大。隨機(jī)訪問(wèn)則相對(duì)較慢。(使用ArrayList代替。) ArrayList類 ArrayList是由數(shù)組實(shí)現(xiàn)的List,并且實(shí)現(xiàn)了可變大小的數(shù)組。它允許所有元素,包括null。ArrayList沒(méi)有同步。size,isEmpty,get,set方法運(yùn)行時(shí)間為常數(shù)。但是add方法開(kāi)銷為分?jǐn)偟某?shù),添加n個(gè)元素需要O(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)。
特點(diǎn):允許對(duì)元素進(jìn)行快速隨機(jī)訪問(wèn),但是向List中間插入與移除元素的速度很慢。ListIterator只應(yīng)該用來(lái)由后向前遍歷ArrayList,而不是用來(lái)插入和移除元素。因?yàn)槟潜萀inkedList開(kāi)銷要大很多。
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)作堆棧使用。基本的push和pop 方法,還有peek方法得到棧頂?shù)脑?,empty方法測(cè)試堆棧是否為空,search方法檢測(cè)一個(gè)元素在堆棧中的位置。Stack剛創(chuàng)建后是空棧。 2,Set接口 Set具有與Collection完全一樣的接口,因此沒(méi)有任何額外的功能,不像前面有幾個(gè)不同的List。實(shí)際上Set就是 Collection,只是行為不同。(這是繼承與多態(tài)思想的典型應(yīng)用:表現(xiàn)不同的行為)。其次,Set是一種不包含重復(fù)的元素的Collection,加入Set的元素必須定義equals()方法以確保對(duì)象的唯一性( 即任意的兩個(gè)元素e1和e2都有e1.equals(e2)=false),與List不同的是,Set接口不保證維護(hù)元素的次序。**后,Set**多有一個(gè)null元素。
很明顯,Set的構(gòu)造函數(shù)有一個(gè)約束條件,傳入的Collection參數(shù)不能包含重復(fù)的元素。
請(qǐng)注意:必須小心操作可變對(duì)象(Mutable Object)。如果一個(gè)Set中的可變?cè)馗淖兞俗陨頎顟B(tài)導(dǎo)致Object.equals(Object)=true將導(dǎo)致一些問(wèn)題。
HashSet類
為快速查找設(shè)計(jì)的Set。存入HashSet的對(duì)象必須定義hashCode()。
LinkedHashSet類:具有HashSet的查詢速度,且內(nèi)部使用鏈表維護(hù)元素的順序(插入的次序)。于是在使用迭代器遍歷Set時(shí),結(jié)果會(huì)按元素插入的次序顯示。
TreeSet類
保存次序的Set, 底層為樹(shù)結(jié)構(gòu)。使用它可以從Set中提取有序的序列。
二、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映射。
方法put(Object key,Object value)添加一個(gè)“值”(想要得東西)和與“值”相關(guān)聯(lián)的“鍵”(key) (使用它來(lái)查找)。方法get(Object key)返回與給定“鍵”相關(guān)聯(lián)的“值”。可以用containsKey()和containsValue()測(cè)試Map中是否包含某個(gè)“鍵”或“值”。標(biāo)準(zhǔn)的Java類庫(kù)中包含了幾種不同的Map:HashMap, TreeMap, LinkedHashMap, WeakHashMap, IdentityHashMap。它們都有同樣的基本接口Map,但是行為、效率、排序策略、保存對(duì)象的生命周期和判定“鍵”等價(jià)的策略等各不相同。
Map同樣對(duì)每個(gè)元素保存一份,但這是基于"鍵"的,Map也有內(nèi)置的排序,因而不關(guān)心元素添加的順序。如果添加元素的順序?qū)δ愫苤匾瑧?yīng)該使用 LinkedHashSet或者LinkedHashMap.
執(zhí)行效率是Map的一個(gè)大問(wèn)題??纯磄et()要做哪些事,就會(huì)明白為什么在ArrayList中搜索“鍵”是相當(dāng)慢的。而這正是HashMap提高速度的地方。HashMap使用了特殊的值,稱為“散列碼”(hash code),來(lái)取代對(duì)鍵的緩慢搜索?!吧⒘写a”是“相對(duì)唯一”用以代表對(duì)象的int值,它是**將該對(duì)象的某些信息進(jìn)行轉(zhuǎn)換而生成的(在下面總結(jié)二:需要的注意的地方有更進(jìn)一步探討)。所有Java對(duì)象都能產(chǎn)生散列碼,因?yàn)閔ashCode()是定義在基類Object中的方法。HashMap就是使用對(duì)象的hashCode()進(jìn)行快速查詢的。此方法能夠顯著提高性能。
Hashtable類 Hashtable繼承Map接口,實(shí)現(xiàn)一個(gè)key-value映射的哈希表。任何非空(non-null)的對(duì)象都可作為key或者value。
添加數(shù)據(jù)使用put(key, value),取出數(shù)據(jù)使用get(key),這兩個(gè)基本操作的時(shí)間開(kāi)銷為常數(shù)。
Hashtable **初始化容量(initialcapacity) 和負(fù)載因子(load factor)兩個(gè)參數(shù)調(diào)整性能。通常缺省的load factor 0.75較好地實(shí)現(xiàn)了時(shí)間和空間的均衡。增大load factor可以節(jié)省空間但相應(yīng)的查找時(shí)間將增大,這會(huì)影響像get和put這樣的操作。
使用Hashtable的簡(jiǎn)單示例如下,將1,2,3放到Hashtable中,他們的key分別是”one”,”two”,”three”:
Hashtable numbers = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“three”, new Integer(3));
要取出一個(gè)數(shù),比如2,用相應(yīng)的key:
Integer n = (Integer)numbers.get(“two”);
System.out.println(“two = ” n);
由于作為key的對(duì)象將**計(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ì)象相同,即obj1.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類似,也是基于散列表的實(shí)現(xiàn)。不同之處在于HashMap是非同步的,并且允許null,即null value和null key。將HashMap視為Collection時(shí)(values()方法可返回Collection),插入和查詢“鍵值對(duì)”的開(kāi)銷是固定的,但其迭代子操作時(shí)間開(kāi)銷和HashMap 的容量成比例。因此,如果迭代操作的性能相當(dāng)重要的話,不要將HashMap的初始化容量(initial capacity)設(shè)得過(guò)高,或者負(fù)載因子(load factor)過(guò)低。
LinkedHashMap 類:類似于HashMap,但是迭代遍歷它時(shí),取得“鍵值對(duì)”的順序是其插入次序,或者是**近**少使用(LRU)的次序。只比HashMap慢一點(diǎn)。而在迭代訪問(wèn)時(shí)發(fā)而更快,因?yàn)樗褂面湵砭S護(hù)內(nèi)部次序。
WeakHashMap類:弱鍵(weak key)Map是一種改進(jìn)的HashMap,它是為解決特殊問(wèn)題設(shè)計(jì)的,對(duì)key實(shí)行“弱引用”,如果一個(gè)key不再被外部所引用(沒(méi)有map之外的引用),那么該key可以被垃圾收集器(GC)回收。
TreeMap類
基于紅黑樹(shù)數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)。查看“鍵”或“鍵值對(duì)”時(shí),它們會(huì)被排序(次序由Comparabel或Comparator決定)。TreeMap的特點(diǎn)在于,你得到的結(jié)果是經(jīng)過(guò)排序的。TreeMap是唯一的帶有subMap()方法的Map,它可以返回一個(gè)子樹(shù)。
IdentifyHashMap類
使用==代替equals()對(duì)“鍵”作比較的hashmap。專為解決特殊問(wèn)題而設(shè)計(jì)。
總結(jié)一:比較
1,數(shù)組(Array),數(shù)組類(Arrays)
Java所有“存儲(chǔ)及隨機(jī)訪問(wèn)一連串對(duì)象”的做法,array是**有效率的一種。但缺點(diǎn)是容量固定且無(wú)法動(dòng)態(tài)改變。array還有一個(gè)缺點(diǎn)是,無(wú)法判斷其中實(shí)際存有多少元素,length只是告訴我們array的容量。
Java中有一個(gè)數(shù)組類(Arrays),專門用來(lái)操作array。數(shù)組類(arrays)中擁有一組static函數(shù)。
equals():比較兩個(gè)array是否相等。array擁有相同元素個(gè)數(shù),且所有對(duì)應(yīng)元素兩兩相等。
fill():將值填入array中。
sort():用來(lái)對(duì)array進(jìn)行排序。
binarySearch():在排好序的array中尋找元素。
System.arraycopy():array的復(fù)制。
若編寫程序時(shí)不知道究竟需要多少對(duì)象,需要在空間不足時(shí)自動(dòng)擴(kuò)增容量,則需要使用容器類庫(kù),array不適用。
2,容器類與數(shù)組的區(qū)別
容器類僅能持有對(duì)象引用(指向?qū)ο蟮闹羔槪皇菍?duì)象信息copy一份至數(shù)列某位置。一旦將對(duì)象置入容器內(nèi),便損失了該對(duì)象的型別信息。
3,容器(Collection)與Map的聯(lián)系與區(qū)別
Collection類型,每個(gè)位置只有一個(gè)元素。
Map類型,持有 key-value 對(duì)(pair),像個(gè)小型數(shù)據(jù)庫(kù)。
Collections是針對(duì)集合類的一個(gè)幫助類。提供了一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程完全化等操作。相當(dāng)于對(duì)Array進(jìn)行類似操作的類——Arrays。
如,Collections.max(Collection coll); 取coll中**大的元素。
Collections.sort(List list); 對(duì)list中元素排序
List,Set,Map將持有對(duì)象一律視為Object型別。
Collection、List、Set、Map都是接口,不能實(shí)例化。繼承自它們的 ArrayList, Vector, HashTable, HashMap是具象class,這些才可被實(shí)例化。
vector容器確切知道它所持有的對(duì)象隸屬什么型別。vector不進(jìn)行邊界檢查。
總結(jié)二:需要注意的地方
1、Collection只能**iterator()遍歷元素,沒(méi)有g(shù)et()方法來(lái)取得某個(gè)元素。
2、Set和Collection擁有一模一樣的接口。但排除掉傳入的Collection參數(shù)重復(fù)的元素。
3、List,可以**get()方法來(lái)一次取出一個(gè)元素。使用數(shù)字來(lái)選擇一堆對(duì)象中的一個(gè),get(0)...。(add/get)
4、Map用 put(k,v) /get(k),還可以使用containsKey()/containsValue()來(lái)檢查其中是否含有某個(gè)key/value。
HashMap會(huì)利用對(duì)象的hashCode來(lái)快速找到key。
哈希碼(hashing)就是將對(duì)象的信息經(jīng)過(guò)一些轉(zhuǎn)變形成一個(gè)獨(dú)一無(wú)二的int值,這個(gè)值存儲(chǔ)在一個(gè)array中。我們都知道所有存儲(chǔ)結(jié)構(gòu)中,array查找速度是**快的。所以,可以加速查找。發(fā)生碰撞時(shí),讓array指向多個(gè)values。即,數(shù)組每個(gè)位置上又生成一個(gè)梿表。
5、Map中元素,可以將key序列、value序列單獨(dú)抽取出來(lái)。
使用keySet()抽取key序列,將map中的所有keys生成一個(gè)Set。
使用values()抽取value序列,將map中的所有values生成一個(gè)Collection。
為什么一個(gè)生成Set,一個(gè)生成Collection?那是因?yàn)?,key總是獨(dú)一無(wú)二的,value允許重復(fù)。
總結(jié)三:如何選擇
從效率角度:
在各種Lists,對(duì)于需要快速插入,刪除元素,應(yīng)該使用LinkedList(可用LinkedList構(gòu)造堆棧stack、隊(duì)列queue),如果需要快速隨機(jī)訪問(wèn)元素,應(yīng)該使用ArrayList。**好的做法是以ArrayList作為缺省選擇。Vector總是比ArrayList慢,所以要盡量避免使用。
在各種Sets中,HashSet通常優(yōu)于HashTree(插入、查找)。只有當(dāng)需要產(chǎn)生一個(gè)經(jīng)過(guò)排序的序列,才用TreeSet。HashTree存在的唯一理由:能夠維護(hù)其內(nèi)元素的排序狀態(tài)。
在各種Maps中HashMap用于快速查找。
**后,當(dāng)元素個(gè)數(shù)固定,用Array,因?yàn)锳rray效率是**高的。
所以結(jié)論:**常用的是ArrayList,HashSet,HashMap,Array。
更近一步分析:
如果程序在單線程環(huán)境中,或者訪問(wèn)僅僅在一個(gè)線程中進(jìn)行,考慮非同步的類,其效率較高,如果多個(gè)線程可能同時(shí)操作一個(gè)類,應(yīng)該使用同步的類。
要特別注意對(duì)哈希表的操作,作為key的對(duì)象要同時(shí)正確復(fù)寫equals方法和hashCode方法。
盡量返回接口而非實(shí)際的類型,如返回List而非ArrayList,這樣如果以后需要將ArrayList換成LinkedList時(shí),客戶端代碼不用改變。這就是針對(duì)抽象編程。
注:本文參考部分網(wǎng)絡(luò)文獻(xiàn)。
相關(guān)推薦:
蘇州JAVA培訓(xùn) 蘇州JAVA培訓(xùn)班 蘇州JAVA培訓(xùn)機(jī)構(gòu)
體驗(yàn)課預(yù)約試聽(tīng)
倒計(jì)時(shí)
12:00:00