java集合是wftc_Java集合
一、集合的由來
通常,我們的程序需要根據(jù)程序運(yùn)行時(shí)才知道創(chuàng)建多少個(gè)對(duì)象。但若非程序運(yùn)行,程序開發(fā)階段,我們根本不知道到底需要多少個(gè)數(shù)量的對(duì)象,甚至不知道它的準(zhǔn)確類型。為了滿足這些常規(guī)的編程需要,我們要求能在任何時(shí)候,任何地點(diǎn)創(chuàng)建任意數(shù)量的對(duì)象,而這些對(duì)象用什么來容納呢?我們首先想到了數(shù)組,但是數(shù)組只能放統(tǒng)一類型的數(shù)據(jù),而且其長度是固定的,那怎么辦呢?集合便應(yīng)運(yùn)而生了!
二、集合是什么?
Java集合類存放于 java.util 包中,是一個(gè)用來存放對(duì)象的容器。
注意:①、集合只能存放對(duì)象。比如你存一個(gè) int 型數(shù)據(jù) 1放入集合中,其實(shí)它是自動(dòng)轉(zhuǎn)換成 Integer 類后存入的,Java中每一種基本類型都有對(duì)應(yīng)的引用類型。
②、集合存放的是多個(gè)對(duì)象的引用,對(duì)象本身還是放在堆內(nèi)存中。
③、集合可以存放不同類型,不限數(shù)量的數(shù)據(jù)類型
數(shù)組和集合的比較
數(shù)組不是面向?qū)ο蟮?#xff0c;存在明顯的缺陷,集合彌補(bǔ)了數(shù)組的缺點(diǎn),比數(shù)組更靈活更實(shí)用,而且不同的集合框架類可適用不同場合。如下:
1:數(shù)組能存放基本數(shù)據(jù)類型和對(duì)象,而集合類存放的都是對(duì)象的引用,而非對(duì)象本身!
2:數(shù)組容易固定無法動(dòng)態(tài)改變,集合類容量動(dòng)態(tài)改變。
3:數(shù)組無法判斷其中實(shí)際存有多少元素,length只告訴了數(shù)組的容量,而集合的size()可以確切知道元素的個(gè)數(shù)
4:集合有多種實(shí)現(xiàn)方式和不同適用場合,不像數(shù)組僅采用順序表方式
5:集合以類的形式存在,具有封裝、繼承、多態(tài)等類的特性,通過簡單的方法和屬性即可實(shí)現(xiàn)各種復(fù)雜操作,大大提高了軟件的開發(fā)效率
三、Java 集合框架圖
四、集合詳解
①、Iterator:迭代器,它是Java集合的頂層接口(不包括 map 系列的集合,Map接口 是 map 系列集合的頂層接口)
Object next():返回迭代器剛越過的元素的引用,返回值是 Object,需要強(qiáng)制轉(zhuǎn)換成自己需要的類型
boolean hasNext():判斷容器內(nèi)是否還有可供訪問的元素
void remove():刪除迭代器剛越過的元素
所以除了 map 系列的集合,我們都能通過迭代器來對(duì)集合中的元素進(jìn)行遍歷。
注意:我們可以在源碼中追溯到集合的頂層接口,比如 Collection 接口,可以看到它繼承的是類 Iterable
那這就得說明一下 Iterator 和 Iterable 的區(qū)別:
Iterable :存在于 java.lang 包中。
我們可以看到,里面封裝 Iterator接口。所以只要實(shí)現(xiàn)了只要實(shí)現(xiàn)了Iterable接口的類,就可以使用Iterator迭代器了。
Iterator :存在于 java.util 包中。核心的方法next(),hasnext(),remove()。
這里我們引用一個(gè)Iterator 的實(shí)現(xiàn)類 ArrayList 來看一下迭代器的使用:暫時(shí)先不管 List 集合是什么,只需要看看迭代器的用法就行了
1 //產(chǎn)生一個(gè) List 集合,典型實(shí)現(xiàn)為 ArrayList。
2 List list = newArrayList();3 //添加三個(gè)元素
4 list.add("Tom");5 list.add("Bob");6 list.add("Marry");7 //構(gòu)造 List 的迭代器
8 Iterator it =list.iterator();9 //通過迭代器遍歷元素
10 while(it.hasNext()){11 Object obj =it.next();12 System.out.println(obj);13 }
②、Collection:List 接口和 Set 接口的父接口
看一下 Collection 集合的使用例子:
1 //我們這里將 ArrayList集合作為 Collection 的實(shí)現(xiàn)類
2 Collection collection = newArrayList();3
4 //添加元素
5 collection.add("Tom");6 collection.add("Bob");7
8 //刪除指定元素
9 collection.remove("Tom");10
11 //刪除所有元素
12 Collection c = newArrayList();13 c.add("Bob");14 collection.removeAll(c);15
16 //檢測是否存在某個(gè)元素
17 collection.contains("Tom");18
19 //判斷是否為空
20 collection.isEmpty();21
22 //利用增強(qiáng)for循環(huán)遍歷集合
23 for(Object obj : collection){24 System.out.println(obj);25 }26 //利用迭代器 Iterator
27 Iterator iterator =collection.iterator();28 while(iterator.hasNext()){29 Object obj =iterator.next();30 System.out.println(obj);31 }
③、List :有序,可以重復(fù)的集合。
由于 List 接口是繼承于 Collection 接口,所以基本的方法如上所示。
1、List 接口的三個(gè)典型實(shí)現(xiàn):
①、List list1 = new ArrayList();
底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢;線程不安全,效率高
②、List list2 = new Vector();
底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢;線程安全,效率低,幾乎已經(jīng)淘汰了這個(gè)集合
③、List list3 = new LinkedList();
底層數(shù)據(jù)結(jié)構(gòu)是鏈表,查詢慢,增刪快;線程不安全,效率高
怎么記呢?我們可以想象:
數(shù)組就像身上編了號(hào)站成一排的人,要找第10個(gè)人很容易,根據(jù)人身上的編號(hào)很快就能找到。但插入、刪除慢,要望某個(gè)位置插入或刪除一個(gè)人時(shí),后面的人身上的編號(hào)都要變。當(dāng)然,加入或刪除的人始終末尾的也快。
鏈表就像手牽著手站成一圈的人,要找第10個(gè)人不容易,必須從第一個(gè)人一個(gè)個(gè)數(shù)過去。但插入、刪除快。插入時(shí)只要解開兩個(gè)人的手,并重新牽上新加進(jìn)來的人的手就可以。刪除一樣的道理。
2、除此之外,List 接口遍歷還可以使用普通 for 循環(huán)進(jìn)行遍歷,指定位置添加元素,替換元素等等。
1 //產(chǎn)生一個(gè) List 集合,典型實(shí)現(xiàn)為 ArrayList
2 List list = newArrayList();3 //添加三個(gè)元素
4 list.add("Tom");5 list.add("Bob");6 list.add("Marry");7 //構(gòu)造 List 的迭代器
8 Iterator it =list.iterator();9 //通過迭代器遍歷元素
10 while(it.hasNext()){11 Object obj =it.next();12 //System.out.println(obj);
13 }14
15 //在指定地方添加元素
16 list.add(2, 0);17
18 //在指定地方替換元素
19 list.set(2, 1);20
21 //獲得指定對(duì)象的索引
22 int i=list.indexOf(1);23 System.out.println("索引為:"+i);24
25 //遍歷:普通for循環(huán)
26 for(int j=0;j
④、Set:典型實(shí)現(xiàn) HashSet()是一個(gè)無序,不可重復(fù)的集合
1、Set hashSet = new HashSet();
①、HashSet:不能保證元素的順序;不可重復(fù);不是線程安全的;集合元素可以為 NULL;
②、其底層其實(shí)是一個(gè)數(shù)組,存在的意義是加快查詢速度。我們知道在一般的數(shù)組中,元素在數(shù)組中的索引位置是隨機(jī)的,元素的取值和元素的位置之間不存在確定的關(guān)系,因此,在數(shù)組中查找特定的值時(shí),需要把查找值和一系列的元素進(jìn)行比較,此時(shí)的查詢效率依賴于查找過程中比較的次數(shù)。而 HashSet 集合底層數(shù)組的索引和值有一個(gè)確定的關(guān)系:index=hash(value),那么只需要調(diào)用這個(gè)公式,就能快速的找到元素或者索引。
③、對(duì)于 HashSet: 如果兩個(gè)對(duì)象通過 equals() 方法返回 true,這兩個(gè)對(duì)象的 hashCode 值也應(yīng)該相同。
1、當(dāng)向HashSet集合中存入一個(gè)元素時(shí),HashSet會(huì)先調(diào)用該對(duì)象的hashCode()方法來得到該對(duì)象的hashCode值,然后根據(jù)hashCode值決定該對(duì)象在HashSet中的存儲(chǔ)位置
1.1、如果 hashCode 值不同,直接把該元素存儲(chǔ)到 hashCode() 指定的位置
1.2、如果 hashCode 值相同,那么會(huì)繼續(xù)判斷該元素和集合對(duì)象的 equals() 作比較
1.2.1、hashCode 相同,equals 為 true,則視為同一個(gè)對(duì)象,不保存在 hashSet()中
1.2.2、hashCode 相同,equals 為 false,則存儲(chǔ)在之前對(duì)象同槽位的鏈表上,這非常麻煩,我們應(yīng)該約束這種情況,即保證:如果兩個(gè)對(duì)象通過 equals() 方法返回 true,這兩個(gè)對(duì)象的 hashCode 值也應(yīng)該相同。
注意:每一個(gè)存儲(chǔ)到 哈希 表中的對(duì)象,都得提供 hashCode() 和 equals() 方法的實(shí)現(xiàn),用來判斷是否是同一個(gè)對(duì)象對(duì)于 HashSet 集合,我們要保證如果兩個(gè)對(duì)象通過 equals() 方法返回 true,這兩個(gè)對(duì)象的 hashCode 值也應(yīng)該相同。
常見的 hashCode()算法:
2、Set linkedHashSet = new LinkedHashSet();
①、不可以重復(fù),有序
因?yàn)榈讓硬捎?鏈表 和 哈希表的算法。鏈表保證元素的添加順序,哈希表保證元素的唯一性
3、Set treeSet = new TreeSet();
TreeSet:有序;不可重復(fù),底層使用 紅黑樹算法,擅長于范圍查詢。
如果使用 TreeSet() 無參數(shù)的構(gòu)造器創(chuàng)建一個(gè) TreeSet 對(duì)象, 則要求放入其中的元素的類必須實(shí)現(xiàn) Comparable 接口所以, 在其中不能放入 null 元素
必須放入同樣類的對(duì)象.(默認(rèn)會(huì)進(jìn)行排序) 否則可能會(huì)發(fā)生類型轉(zhuǎn)換異常.我們可以使用泛型來進(jìn)行限制
1 Set treeSet = newTreeSet();2 treeSet.add(1); //添加一個(gè) Integer 類型的數(shù)據(jù)
3 treeSet.add("a"); //添加一個(gè) String 類型的數(shù)據(jù)
4 System.out.println(treeSet); //會(huì)報(bào)類型轉(zhuǎn)換異常的錯(cuò)誤
自動(dòng)排序:添加自定義對(duì)象的時(shí)候,必須要實(shí)現(xiàn) Comparable 接口,并要覆蓋 compareTo(Object obj) 方法來自定義比較規(guī)則
如果 this > obj,返回正數(shù) 1
如果 this < obj,返回負(fù)數(shù) -1
如果 this = obj,返回 0 ,則認(rèn)為這兩個(gè)對(duì)象相等
兩個(gè)對(duì)象通過 Comparable 接口 compareTo(Object obj) 方法的返回值來比較大小, 并進(jìn)行升序排列
定制排序: 創(chuàng)建 TreeSet 對(duì)象時(shí), 傳入 Comparator 接口的實(shí)現(xiàn)類.?要求: Comparator 接口的 compare 方法的返回值和 兩個(gè)元素的 equals() 方法具有一致的返回值
1 public classTreeSetTest {2 public static voidmain(String[] args) {3 Person p1 = new Person(1);4 Person p2 = new Person(2);5 Person p3 = new Person(3);6
7 Set set = new TreeSet<>(newPerson());8 set.add(p1);9 set.add(p2);10 set.add(p3);11 System.out.println(set); //結(jié)果為[1, 2, 3]
12 }13
14 }15
16 class Person implements Comparator{17 public intage;18 publicPerson(){}19 public Person(intage){20 this.age =age;21 }22 @Override23 /***24 * 根據(jù)年齡大小進(jìn)行排序25 */
26 public intcompare(Person o1, Person o2) {27 //TODO Auto-generated method stub
28 if(o1.age >o2.age){29 return 1;30 }else if(o1.age
37 @Override38 publicString toString() {39 //TODO Auto-generated method stub
40 return ""+this.age;41 }42 }
當(dāng)需要把一個(gè)對(duì)象放入 TreeSet 中,重寫該對(duì)象對(duì)應(yīng)的 equals() 方法時(shí),應(yīng)保證該方法與 compareTo(Object obj) 方法有一致的結(jié)果
以上三個(gè) Set 接口的實(shí)現(xiàn)類比較:
共同點(diǎn):
1、都不允許元素重復(fù)
2、都不是線程安全的類,解決辦法:Set set = Collections.synchronizedSet(set 對(duì)象)
不同點(diǎn):
1、HashSet:不保證元素的添加順序,底層采用 哈希表算法,查詢效率高。判斷兩個(gè)元素是否相等,equals() 方法返回 true,hashCode() 值相等。即要求存入 HashSet 中的元素要覆蓋 equals() 方法和 hashCode()方法
2、LinkedHashSet:HashSet 的子類,底層采用了 哈希表算法以及 鏈表算法,既保證了元素的添加順序,也保證了查詢效率。但是整體性能要低于 HashSet
3、TreeSet:不保證元素的添加順序,但是會(huì)對(duì)集合中的元素進(jìn)行排序。底層采用 紅-黑 樹算法(樹結(jié)構(gòu)比較適合范圍查詢)
⑤、Map:key-value 的鍵值對(duì),key 不允許重復(fù),value 可以
1、嚴(yán)格來說 Map 并不是一個(gè)集合,而是兩個(gè)集合之間 的映射關(guān)系。
2、這兩個(gè)集合沒每一條數(shù)據(jù)通過映射關(guān)系,我們可以看成是一條數(shù)據(jù)。即 Entry(key,value)。Map 可以看成是由多個(gè) Entry 組成。
3、因?yàn)?Map 集合即沒有實(shí)現(xiàn)于 Collection 接口,也沒有實(shí)現(xiàn) Iterable 接口,所以不能對(duì) Map 集合進(jìn)行 for-each 遍歷。
1 Map hashMap = new HashMap<>();2 //添加元素到 Map 中
3 hashMap.put("key1", "value1");4 hashMap.put("key2", "value2");5 hashMap.put("key3", "value3");6 hashMap.put("key4", "value4");7 hashMap.put("key5", "value5");8
9 //刪除 Map 中的元素,通過 key 的值
10 hashMap.remove("key1");11
12 //通過 get(key) 得到 Map 中的value
13 Object str1 = hashMap.get("key1");14
15 //可以通過 添加 方法來修改 Map 中的元素
16 hashMap.put("key2", "修改 key2 的 Value");17
18 //通過 map.values() 方法得到 Map 中的 value 集合
19 Collection value =hashMap.values();20 for(Object obj : value){21 //System.out.println(obj);
22 }23
24 //通過 map.keySet() 得到 Map 的key 的集合,然后 通過 get(key) 得到 Value
25 Set set =hashMap.keySet();26 for(String str : set){27 Object obj =hashMap.get(str);28 //System.out.println(str+"="+obj);
29 }30
31 //通過 Map.entrySet() 得到 Map 的 Entry集合,然后遍歷
32 Set> entrys =hashMap.entrySet();33 for(Map.Entryentry: entrys){34 String key =entry.getKey();35 Object value2 =entry.getValue();36 System.out.println(key+"="+value2);37 }38
39 System.out.println(hashMap);
map常用的實(shí)現(xiàn)類:
HashMap、TreeMap、LinkedHashMap、Hashtable等
HashMap:鍵值對(duì),key不能重復(fù),但是value可以重復(fù);key的實(shí)現(xiàn)就是HashSet;value對(duì)應(yīng)著放;允許null的鍵或值;
Hashtable:線程安全的,不允許null的鍵或值;
Properties::key和value都是String類型,用來讀配置文件;
TreeMap:對(duì)key排好序的Map; key 就是TreeSet, value對(duì)應(yīng)每個(gè)key; key要實(shí)現(xiàn)Comparable接口或TreeMap有自己的構(gòu)造器;
LinkedHashMap: 此實(shí)現(xiàn)與 HashMap 的不同之處在于,后者維護(hù)著一個(gè)運(yùn)行于所有條目的雙重鏈接列表。存儲(chǔ)的數(shù)
據(jù)是有序的。
⑥、Map 和 Set 集合的關(guān)系
1、都有幾個(gè)類型的集合。HashMap 和 HashSet ,都采 哈希表算法;TreeMap 和 TreeSet 都采用 紅-黑樹算法;LinkedHashMap 和 LinkedHashSet 都采用 哈希表算法和紅-黑樹算法。
2、分析 Set 的底層源碼,我們可以看到,Set 集合 就是 由 Map 集合的 Key 組成。
總結(jié):
結(jié)構(gòu)圖詳解:
發(fā)現(xiàn)一個(gè)特點(diǎn),上述所有的集合類,除了 map 系列的集合,即左邊集合都實(shí)現(xiàn)了?Iterator?接口,這是一個(gè)用于遍歷集合中元素的接口,主要hashNext(),next(),remove()三種方法。它的一個(gè)子接口?ListIterator?在它的基礎(chǔ)上又添加了三種方法,分別是 add(),previous(),hasPrevious()。也就是說如果實(shí)現(xiàn) Iterator 接口,那么在遍歷集合中元素的時(shí)候,只能往后遍歷,被遍歷后的元素不會(huì)再被遍歷到,通常無序集合實(shí)現(xiàn)的都是這個(gè)接口,比如HashSet;而那些元素有序的集合,實(shí)現(xiàn)的一般都是 LinkedIterator接口,實(shí)現(xiàn)這個(gè)接口的集合可以雙向遍歷,既可以通過next()訪問下一個(gè)元素,又可以通過previous()訪問前一個(gè) 元素,比如ArrayList。
還有一個(gè)特點(diǎn)就是抽象類的使用。如果要自己實(shí)現(xiàn)一個(gè)集合類,去實(shí)現(xiàn)那些抽象的接口會(huì)非常麻煩,工作量很大。這個(gè)時(shí)候就可以使用抽象類,這些抽象類中給我們提供了許多現(xiàn)成的實(shí)現(xiàn),我們只需要根據(jù)自己的需求重寫一些方法或者添加一些方法就可以實(shí)現(xiàn)自己需要的集合類,工作量大大降低。
HashMap特點(diǎn):
Map 主要用于存儲(chǔ)鍵(key)值(value)對(duì),根據(jù)鍵得到值,因此鍵不允許重復(fù),但允許值重復(fù)。
HashMap 是一個(gè)最常用的Map,它根據(jù)鍵的HashCode 值存儲(chǔ)數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度。
HashMap最多只允許一條記錄的鍵為Null;允許多條記錄的值為 Null;
HashMap不支持線程的同步,即任一時(shí)刻可以有多個(gè)線程同時(shí)寫HashMap;可能會(huì)導(dǎo)致數(shù)據(jù)的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力。
HashMap實(shí)現(xiàn)原理---散列
Hash哈希算法的意義在于提供了一種快速存取數(shù)據(jù)的方法,它用一種算法建立鍵值與真實(shí)值之間的對(duì)應(yīng)關(guān)系。散列表又稱為哈希表。散列表算法的基本思想是:以結(jié)點(diǎn)的關(guān)鍵字為自變量,通過一定的函數(shù)關(guān)系(散列函數(shù))計(jì)算出對(duì)應(yīng)的函數(shù)值,以這個(gè)值作為該結(jié)點(diǎn)存儲(chǔ)在散列表中地址。
當(dāng)散列表中的元素存放太滿,就必須進(jìn)行再散列,將產(chǎn)生一個(gè)新的散列表,所有元素存放到新的散列表中,原先的散列表將被刪除。在Java語言中,通過負(fù)載因子(load factor)來決定何時(shí)對(duì)散列表進(jìn)行再散列。例如:如果負(fù)載因子0.75,當(dāng)散列表中已經(jīng)有75%位置已經(jīng)放滿,那么將進(jìn)行再散列。
負(fù)載因子越高(越接近1.0),內(nèi)存的使用效率越高,元素的尋找時(shí)間越長。負(fù)載因子越低(越接近0.0),元素的尋找時(shí)間越短,內(nèi)存浪費(fèi)越多。
何時(shí)需重寫equals?
當(dāng)一個(gè)類有自己特有的“邏輯相等”概念(不同于對(duì)象身份的概念);
Object類僅僅提供了一個(gè)對(duì)引用的比較,如果兩個(gè)引用不是同一個(gè)那就返回false,這是無法滿足大多數(shù)對(duì)象比較的需要的,所以要覆蓋;
使用==操作符檢查實(shí)參是否為指向?qū)ο蟮囊谩?/p>
使用instanceof操作符檢查實(shí)參是否為正確的類型
把實(shí)參轉(zhuǎn)換到正確的類型;
對(duì)于該類中每一個(gè)“關(guān)鍵”域,檢查實(shí)參中的域與當(dāng)前對(duì)象中對(duì)應(yīng)的域值是否匹 配。對(duì)于既不是float也不是double類型的基本類型的域,可以使用==操作符 進(jìn)行比較;對(duì)于對(duì)象引用類型的域,可以遞歸地調(diào)用所引用的對(duì)象的equals方法,對(duì)于float和double類型的域,先轉(zhuǎn)換成int或long類型的值,然后使用==操作符比較;
當(dāng)你編寫完成了equals方法之后,應(yīng)該問自己三個(gè)問題:它是否是對(duì)稱的、傳 遞的、一致的? 如果答案是否定的,那么請(qǐng)找到 這些特性未能滿足的原因,再修改equals方法的代碼
equals()和hashCode()同時(shí)覆寫
尤其強(qiáng)調(diào)當(dāng)一個(gè)對(duì)象被當(dāng)作鍵值(或索引)來使用的時(shí)候要重寫這兩個(gè)方法;
覆寫equals后,兩個(gè)不同實(shí)例可能在邏輯上相等,但是根據(jù)Object.hashCode方法卻產(chǎn)生不同的散列碼,違反“相等的對(duì)象必須具有相等的散列碼”。
導(dǎo)致,當(dāng)你用其中的一個(gè)作為鍵保存到hashMap、hasoTable或hashSet中,再以“相等的”找另 一個(gè)作為鍵值去查找他們的時(shí)候,則根本找不到
不同類型的hashCode取值
如果該域是布爾型的,計(jì)算(f?0:1)
如果是char,short,byte或int,計(jì)算(int)f
如果是long類型,計(jì)算(int)(f^(f>>>32))
如果是float類型,計(jì)算Float.floatToIntBits(f)
如果是double類型,計(jì)算Dobule.doubleToLongBits(f)
如果該域是一個(gè)對(duì)象引用,遞歸調(diào)用hashCode
如果該域是一個(gè)數(shù)組,則把每個(gè)元素當(dāng)做單獨(dú)的域來處理,對(duì)每個(gè)重要的元素計(jì)算一個(gè)散列碼,
Map集合比較:
HashMap的存入順序和輸出順序無關(guān)。
LinkedHashMap 則保留了鍵值對(duì)的存入順序。
TreeMap則是對(duì)Map中的元素進(jìn)行排序。
因?yàn)镠ashMap和LinkedHashMap 存儲(chǔ)數(shù)據(jù)的速度比直接使用TreeMap 要快,存取效率要高。
當(dāng)完成了所有的元素的存放后,我們?cè)賹?duì)整個(gè)的Map中的元素進(jìn)行排序。這樣可以提高整個(gè)程序的運(yùn)行的效率,縮短執(zhí)行時(shí)間。
注意:TreeMap中是根據(jù)鍵(Key)進(jìn)行排序的。而如果我們要使用TreeMap來進(jìn)行正常的排序的話,Key 中存放的對(duì)象必須實(shí)現(xiàn)Comparable 接口。
Map常用方法:
Object put(Object key,Object value):用來存放一個(gè)鍵-值對(duì)Map中
Object remove(Object key):根據(jù)key(鍵),移除鍵-值對(duì),并將值返回
void putAll(Map mapping) :將另外一個(gè)Map中的元素存入當(dāng)前的Map中
void clear() :清空當(dāng)前Map中的元素
Object get(Object key) :根據(jù)key(鍵)取得對(duì)應(yīng)的值
boolean containsKey(Object key) :判斷Map中是否存在某鍵(key)
boolean containsValue(Object value):判斷Map中是否存在某值(value)
public Set keySet() :返回所有的鍵(key),并使用Set容器存放
public Collection values() :返回所有的值(Value),并使用Collection存放
public Set entrySet() :返回一個(gè)實(shí)現(xiàn) Map.Entry 接口的元素 Set
1.ArrayList: 元素單個(gè),效率高,多用于查詢
2.Vector: 元素單個(gè),線程安全,多用于查詢
3.LinkedList:元素單個(gè),多用于插入和刪除
4.HashMap: 元素成對(duì),元素可為空
5.HashTable: 元素成對(duì),線程安全,元素不可為空
HashMap和Hashtable的區(qū)別:
相同點(diǎn):HashMap和Hashtable都是java的集合類,都可以用來存放java對(duì)象
不同點(diǎn):
1.歷史原因:Hashtable是基于陳舊的Dictionary類的,HashMap是java 1.2引進(jìn)的Map接口的一個(gè)現(xiàn)實(shí)。
2.同步性:Hashtable是同步的,這個(gè)類中的一些方法保證了Hashtable中的對(duì)象是線程安全的,而HashMap則是異步的,因此HashMap中的對(duì)象并不是線程安全的,因?yàn)橥降囊髸?huì)影響執(zhí)行的效率,所以如果你不需要線程安全的結(jié)合那么使用HashMap是一個(gè)很好的選擇,這樣可以避免由于同步帶來的不必要的性能開銷,從而提高效率,我們一般所編寫的程序都是異步的,但如果是服務(wù)器端的代碼除外。
3.值:HashMap可以讓你將空值作為一個(gè)表的條目的key或value,Hashtable是不能放入空值(null)的
ArrayList和Vector的區(qū)別:
相同點(diǎn):ArrayList與Vector都是java的集合類,都是用來存放java對(duì)象
不同點(diǎn):
1.同步性:Vector是同步的,這個(gè)類的一些方法保證了Vector中的對(duì)象的線程安全的,而ArrayList則是異步的,因此ArrayList中的對(duì)象并不 是線程安全的,因?yàn)橥揭髸?huì)影響執(zhí)行的效率,所以你不需要線程安全的集合那么使用ArrayList是一個(gè)很好的選擇,這樣可以避免由于同步帶來的不必 要的性能開銷。
2.數(shù)據(jù)增長:從內(nèi)部實(shí)現(xiàn)的機(jī)制來講,ArrayList和Vector都是使用數(shù)組(Array)來控制集合中的對(duì)象,當(dāng)你向兩種類型中增加元素的時(shí)候,如果元素的數(shù)目超過了內(nèi)部數(shù)組目前的長度他們都需要擴(kuò)展內(nèi)部數(shù)組的長度,Vector缺省情況下自動(dòng)增長原來一倍的數(shù)組長度,ArrayList是原來的50%,所以最后你獲得的這個(gè)集合所占的空間總是比你實(shí)際需要的要大,所以如果你要在集合中保存大量的數(shù)據(jù),那么使用Vector有一些優(yōu)勢,因?yàn)槟憧梢酝ㄟ^設(shè)置集合的初始大小來避免不必要的資源開銷。
總結(jié):
1)如果要求線程安全,使用Vector,Hashtable
2)如果不要求線程安全,使用ArrayList,LinkedList,HashMap
3)如果要求鍵值對(duì),則使用HashMap,Hashtable
4)如果數(shù)據(jù)量很大,又要求線程安全考慮Vector
arraylist和linkedlist聯(lián)系與區(qū)別
1.ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)。
2.對(duì)于隨機(jī)訪問get和set,ArrayList覺得優(yōu)于LinkedList,因?yàn)長inkedList要移動(dòng)指針。
3.對(duì)于新增和刪除操作add和remove,LinedList比較占優(yōu)勢,因?yàn)锳rrayList要移動(dòng)數(shù)據(jù)。 這一點(diǎn)要看實(shí)際情況的。若只對(duì)單條數(shù)據(jù)插入或刪除,ArrayList的速度反而優(yōu)于LinkedList。但若是批量隨機(jī)的插入刪除數(shù)據(jù),LinkedList的速度大大優(yōu)于ArrayList. 因?yàn)锳rrayList每插入一條數(shù)據(jù),要移動(dòng)插入點(diǎn)及之后的所有數(shù)據(jù)。
HashMap與TreeMap聯(lián)系與區(qū)別
1、 HashMap通過hashcode對(duì)其內(nèi)容進(jìn)行快速查找,而TreeMap中所有的元素都保持著某種固定的順序,如果你需要得到一個(gè)有序的結(jié)果你就應(yīng)該使用TreeMap(HashMap中元素的排列順序是不固定的)。
2、在Map 中插入、刪除和定位元素,HashMap是最好的選擇。但如果您要按自然順序或自定義順序遍歷鍵,那么TreeMap會(huì)更好。使用HashMap要求添加的鍵類明確定義了hashCode()和 equals()的實(shí)現(xiàn)。
兩個(gè)map中的元素一樣,但順序不一樣,導(dǎo)致hashCode()不一樣。
同樣做測試:
在HashMap中,同樣的值的map,順序不同,equals時(shí),false;
而在treeMap中,同樣的值的map,順序不同,equals時(shí),true,說明,treeMap在equals()時(shí)是整理了順序了的。
總結(jié)
以上是生活随笔為你收集整理的java集合是wftc_Java集合的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php怎么看回调的异步通知的数据_php
- 下一篇: java窗体添加背景图片_Java项目实