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