系列文章目錄
提示:這里可以添加系列文章的所有文章的目錄,目錄需要自己手動(dòng)添加
例如:第一章 Python 機(jī)器學(xué)習(xí)入門之pandas的使用
提示:寫完文章后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔
前言
說(shuō)說(shuō)HashMap 和 HashSet 區(qū)別?
HashSet 底層就是基于 HashMap 實(shí)現(xiàn)的。兩者主要區(qū)別:
說(shuō)下HashMap 和 Hashtable 的區(qū)別?
線程是否安全: HashMap 是非線程安全的,Hashtable 是線程安全的,因?yàn)?Hashtable 內(nèi)部的方法基本都經(jīng)過(guò)synchronized 修飾。(如果你要保證線程安全的話就使用 ConcurrentHashMap 吧?。?/p>
效率:因?yàn)镠ashtable加了synchronized鎖。所以HashMap 要比 Hashtable 效率高一點(diǎn)。另外,Hashtable 基本被淘汰,不要在代碼中使用它
對(duì) Null key 和 Null value 的支持: HashMap 可以存儲(chǔ) null 的 key 和 value,但 null 作為鍵只能有一個(gè),null 作為值可以有多個(gè);Hashtable 不允許有 null 鍵和 null 值,否則會(huì)拋出 NullPointerException。
初始容量大小和每次擴(kuò)充容量大小的不同 :
① 創(chuàng)建時(shí)如果不指定容量初始值,Hashtable 默認(rèn)的初始大小為 11,之后每次擴(kuò)充,容量變?yōu)樵瓉?lái)的 2n+1。HashMap 默認(rèn)的初始化大小為 16。之后每次擴(kuò)充,容量變?yōu)樵瓉?lái)的 2 倍。
② 創(chuàng)建時(shí)如果給定了容量初始值,那么 Hashtable 會(huì)直接使用你給定的大小,而 HashMap 會(huì)將其擴(kuò)充為 2 的冪次方大小。也就是說(shuō) HashMap 總是使用 2 的冪作為哈希表的大小。
為什么HashTable 的key和value 不能為 null 值 ?
key V 不能為 null 主要是為了線程安全所考慮
當(dāng)通過(guò)get(k)獲取對(duì)應(yīng)的value時(shí),如果獲取到的是null時(shí),無(wú)法判斷,它是put(k,v)的時(shí)候value為null,還是這個(gè)key從來(lái)沒(méi)有做過(guò)映射。假如線程1調(diào)用m.contains(key)返回true,然后在調(diào)用m.get(key),這時(shí)的m可能已經(jīng)不同了。因?yàn)榫€程2可能在線程1調(diào)用m.contains(key)時(shí),刪除了key節(jié)點(diǎn),這樣就會(huì)導(dǎo)致線程1得到的結(jié)果不明確,產(chǎn)生多線程安全問(wèn)題,因此,Hashmap和ConcurrentHashMap的key和value不能為null。
而HashMap允許key和value為null,在單線程時(shí),調(diào)用contains()和get()不會(huì)出現(xiàn)問(wèn)題,但是多線程下,就是線程不安全的。如果要保證線程安全,應(yīng)該使用ConcurrentHashMap 。
說(shuō)說(shuō)LinkedHashMap 的實(shí)現(xiàn)原理?
LinkedHashMap也是基于HashMap 實(shí)現(xiàn)的,不同的是它定義了一個(gè)Entry header,這個(gè)header不是放在Table里,它是額外獨(dú)立出來(lái)的。LinkedHashMap通過(guò)繼承hashMap 中的Entry,并添加兩個(gè)屬性Entrybefore,after和 header結(jié)合起來(lái)組成一個(gè)雙向鏈表,來(lái)實(shí)現(xiàn)按插入順序或訪問(wèn)順序排序。
LinkedHashMap定義了排序模式 accessOrder,該屬性為boolean型變量,對(duì)于訪問(wèn)順序,為true,對(duì)于插入順序,則為false。一般情況下,不必指定排序模式,其迭代順序即為默認(rèn)為插入順序。
說(shuō)一下HashMap 和 TreeMap 區(qū)別?
一、集合容器概述
1、 什么是集合 ,集合的特點(diǎn) ?
集合就是一個(gè)放數(shù)據(jù)的容器,準(zhǔn)確的說(shuō)是放數(shù)據(jù)對(duì)象引用的容器
集合類存放的都是對(duì)象的引用,而不是對(duì)象的本身
集合類型主要有3種:set(集)、list(列表)和map(映射)。
集合的特點(diǎn)主要有如下兩點(diǎn):
集合用于存儲(chǔ)對(duì)象的容器,對(duì)象是用來(lái)封裝數(shù)據(jù),對(duì)象多了也需要存儲(chǔ)集中式管理。
和數(shù)組對(duì)比對(duì)象的大小不確定。因?yàn)榧鲜强勺冮L(zhǎng)度的。數(shù)組需要提前定義大小
2、集合和數(shù)組的區(qū)別 ?
數(shù)組是固定長(zhǎng)度的;集合可變長(zhǎng)度的。
數(shù)組可以存儲(chǔ)基本數(shù)據(jù)類型,也可以存儲(chǔ)引用數(shù)據(jù)類型;集合只能存儲(chǔ)引用數(shù)據(jù)類型。
數(shù)組存儲(chǔ)的元素必須是同一個(gè)數(shù)據(jù)類型;集合存儲(chǔ)的對(duì)象可以是不同數(shù)據(jù)類型。
3、使用集合框架的好處 ?
容量自增長(zhǎng);
提供了高性能的數(shù)據(jù)結(jié)構(gòu)和算法,使編碼更輕松,提高了程序速度和質(zhì)量;
可以方便地?cái)U(kuò)展或改寫集合,提高代碼復(fù)用性和可操作性。
4、說(shuō)說(shuō)Java中常用的容器有哪些?也就是常用的集合類有哪些?
.
Collection接口 和 Map接口 是所有集合框架的父接口:
Collection接口的子接口包括:Set接口和List接口
Set接口的實(shí)現(xiàn)類主要有:HashSet、TreeSet、LinkedHashSet等
List接口的實(shí)現(xiàn)類主要有:ArrayList、LinkedList、Stack以及Vector等
Map接口的實(shí)現(xiàn)類主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
5、List,Set,Map三者的區(qū)別 ?
Java 容器分為 Collection 和 Map 兩大類,Collection集合的子接口有Set、List、Queue三種子接
口。我們比較常用的是Set、List,Map接口不是collection的子接口。
Collection集合主要有List和Set兩大接口
List:一個(gè)有序(元素存入集合的順序和取出的順序一致)容器,元素可以重復(fù),可以插入多
個(gè)null元素,元素都有索引。常用的實(shí)現(xiàn)類有 ArrayList、LinkedList 和 Vector。
Set:一個(gè)無(wú)序(存入和取出順序有可能不一致)容器,不可以存儲(chǔ)重復(fù)元素,只允許存入一
個(gè)null元素,必須保證元素唯一性。Set 接口常用實(shí)現(xiàn)類是 HashSet、LinkedHashSet 以及TreeSet。
Map是一個(gè)鍵值對(duì)集合,存儲(chǔ)鍵、值和之間的映射。 Key無(wú)序,唯一;value 不要求有序,允許重
復(fù)。Map沒(méi)有繼承于Collection接口,從Map集合中檢索元素時(shí),只要給出鍵對(duì)象,就會(huì)返回對(duì)應(yīng)
的值對(duì)象。
Map 的常用實(shí)現(xiàn)類:HashMap、TreeMap、HashTable、LinkedHashMap、ConcurrentHashMap
6、集合框架底層數(shù)據(jù)結(jié)構(gòu)
Collection
List
Arraylist: Object數(shù)組
Vector: Object數(shù)組
LinkedList: 雙向循環(huán)鏈表*
Set
HashSet(無(wú)序,唯一):基于 HashMap 實(shí)現(xiàn)的,底層采用 HashMap 來(lái)保存元素
LinkedHashSet: LinkedHashSet 繼承與 HashSet,并且其內(nèi)部是通過(guò) LinkedHashMap 來(lái)實(shí)現(xiàn)的。有點(diǎn)類似于我們之前說(shuō)的LinkedHashMap 其內(nèi)部是基于 Hashmap 實(shí)現(xiàn)一樣,不過(guò)還是有一點(diǎn)點(diǎn)區(qū)別的。
TreeSet(有序,唯一): 紅黑樹(shù)(自平衡的排序二叉樹(shù)。)
Map
HashMap: JDK1.8之前HashMap由數(shù)組+鏈表組成的,數(shù)組是HashMap的主體,鏈表則是
主要為了解決哈希沖突而存在的(“拉鏈法”解決沖突).JDK1.8以后在解決哈希沖突時(shí)有了較
大的變化,當(dāng)鏈表長(zhǎng)度大于閾值(默認(rèn)為8)時(shí),將鏈表轉(zhuǎn)化為紅黑樹(shù),以減少搜索時(shí)間。
LinkedHashMap:LinkedHashMap 繼承自 HashMap,所以它的底層仍然是基于拉鏈?zhǔn)缴?br> 列結(jié)構(gòu)即由數(shù)組和鏈表或紅黑樹(shù)組成。另外,LinkedHashMap 在上面結(jié)構(gòu)的基礎(chǔ)上,增加
了一條雙向鏈表,使得上面的結(jié)構(gòu)可以保持鍵值對(duì)的插入順序。同時(shí)通過(guò)對(duì)鏈表進(jìn)行相應(yīng)的
操作,實(shí)現(xiàn)了訪問(wèn)順序相關(guān)邏輯。
HashTable: 數(shù)組+鏈表組成的,數(shù)組是 HashMap 的主體,鏈表則是主要為了解決哈希沖突
而存在的
TreeMap: 紅黑樹(shù)(自平衡的排序二叉樹(shù))
7、哪些集合類是線程安全的?
Vector:就比Arraylist多了個(gè) synchronized (線程安全),因?yàn)樾瘦^低,現(xiàn)在已經(jīng)不太建議使
用。
hashTable:就比hashMap多了個(gè)synchronized (線程安全),不建議使用。
ConcurrentHashMap:是Java5中支持高并發(fā)、高吞吐量的線程安全HashMap實(shí)現(xiàn)。它由Segment數(shù)組結(jié)構(gòu)和HashEntry數(shù)組結(jié)構(gòu)組成。Segment數(shù)組在ConcurrentHashMap里扮演鎖的角色,HashEntry則用于存儲(chǔ)鍵-值對(duì)數(shù)據(jù)。一個(gè)ConcurrentHashMap里包含一個(gè)Segment數(shù)組,Segment的結(jié)構(gòu)和HashMap類似,是一種數(shù)組和鏈表結(jié)構(gòu);一個(gè)Segment里包含一個(gè)HashEntry數(shù)組,每個(gè)HashEntry是一個(gè)鏈表結(jié)構(gòu)的元素;每個(gè)Segment守護(hù)著一個(gè)HashEntry數(shù)組里的元素,當(dāng)對(duì)HashEntry數(shù)組的數(shù)據(jù)進(jìn)行修改時(shí),必須首先獲得它對(duì)應(yīng)的Segment鎖。(推薦使用)
8、 Java集合的快速失敗機(jī)制 “fail-fast”?
是java集合的一種錯(cuò)誤檢測(cè)機(jī)制,當(dāng)多個(gè)線程對(duì)集合進(jìn)行結(jié)構(gòu)上的改變的操作時(shí),有可能會(huì)產(chǎn)生
fail-fast 機(jī)制。
例如:假設(shè)存在兩個(gè)線程(線程1、線程2),線程1通過(guò)Iterator在遍歷集合A中的元素,在某個(gè)時(shí)
候線程2修改了集合A的結(jié)構(gòu)(是結(jié)構(gòu)上面的修改,而不是簡(jiǎn)單的修改集合元素的內(nèi)容),那么這
個(gè)時(shí)候程序就會(huì)拋出 ConcurrentModificationException 異常,從而產(chǎn)生fail-fast機(jī)制。
原因:迭代器在遍歷時(shí)直接訪問(wèn)集合中的內(nèi)容,并且在遍歷過(guò)程中使用一個(gè) modCount 變量。集
合在被遍歷期間如果內(nèi)容發(fā)生變化,就會(huì)改變modCount的值。每當(dāng)?shù)魇褂胔ashNext()/next()
遍歷下一個(gè)元素之前,都會(huì)檢測(cè)modCount變量是否為expectedmodCount值,是的話就返回遍
歷;否則拋出異常,終止遍歷。
解決辦法:
在遍歷過(guò)程中,所有涉及到改變modCount值得地方全部加上synchronized。
使用CopyOnWriteArrayList來(lái)替換ArrayList
9、怎么確保一個(gè)集合不能被修改?
可以使用 Collections. unmodifiableCollection(Collection c) 方法來(lái)創(chuàng)建一個(gè)只讀集合,這樣改變
集合的任何操作都會(huì)拋出 Java. lang. UnsupportedOperationException 異常。
示例代碼如下:
List<String> list = new ArrayList<>();
list. add("x");
Collection<String> clist = Collections. unmodifiableCollection(list);
clist. add("y"); // 運(yùn)行時(shí)此行報(bào)錯(cuò)
System. out. println(list. size());
List
10 、 List 和 Set 的區(qū)別 ?
List:有序集合(元素存入集合的順序和取出的順序一致)容器,元素可以重復(fù),可以插入多
個(gè)null元素,元素都有索引。常用的實(shí)現(xiàn)類有 ArrayList、LinkedList 和 Vector。
Set:無(wú)序集合(存入和取出順序有可能不一致)容器,不可以存儲(chǔ)重復(fù)元素,只允許存入一
個(gè)null元素,必須保證元素唯一性。Set 接口常用實(shí)現(xiàn)類是 HashSet、LinkedHashSet 以及TreeSet。
11 、 迭代器 Iterator 是什么?
Iterator 接口提供遍歷任何 Collection 的接口。我們可以從一個(gè) Collection 中使用迭代器方法來(lái)
獲取迭代器實(shí)例。迭代器取代了 Java 集合框架中的 Enumeration,迭代器允許調(diào)用者在迭代過(guò)程
中移除元素。
因?yàn)樗蠧ollection接繼承了Iterator迭代器
public interface Collection<E> extends Iterable<E>{
// Query Operations
}
12、Iterator 怎么使用?有什么特點(diǎn)?
Iterator 使用代碼如下:
先調(diào)用iterator 方法獲取到 迭代器,然會(huì)判斷是否有元素或者下一個(gè)元素,再調(diào)用 next 獲取元素
List<String> list = new ArrayList<>();
Iterator<String> it = list. iterator();
while(it. hasNext()){
String obj = it. next();
System. out. println(obj);
}
特點(diǎn)
Iterator 的特點(diǎn)是只能單向遍歷,但是更加安全,因?yàn)樗梢源_保,在當(dāng)前遍歷的集合元素被更改
的時(shí)候,就會(huì)拋出 ConcurrentModificationException 異常。
- 如何邊遍歷邊移除 Collection 中的元素?
- Iterator 和 ListIterator 有什么區(qū)別?
- 遍歷一個(gè) List 有哪些不同的方式?每種方法的實(shí)現(xiàn)原理是什么?Java 中 List遍歷的最佳實(shí)踐是什么?
- 如何實(shí)現(xiàn)數(shù)組和 List 之間的轉(zhuǎn)換?
8.comparable和comparator的區(qū)別?
9.Collection和Collections有什么區(qū)別?
10.說(shuō)一下PriorityQueue?
ArrayList
- Array 和 ArrayList 有何區(qū)別?
- 如何實(shí)現(xiàn) Array 和 List 之間的轉(zhuǎn)換?
2.詳細(xì)說(shuō)說(shuō) Arraylist 和 LinkedList的區(qū)別? - 說(shuō)一下 ArrayList 的優(yōu)缺點(diǎn)
3.ArrayList實(shí)現(xiàn) RandomAccess接口有何作用?
5.說(shuō)說(shuō)ArrayList 的擴(kuò)容機(jī)制?
6.Array和ArrayList有何區(qū)別?
4.說(shuō)一說(shuō)Vector 和 ArrayList 的區(qū)別? - 插入數(shù)據(jù)時(shí),ArrayList、LinkedList、Vector誰(shuí)速度較快?闡述
- 多線程場(chǎng)景下如何使用 ArrayList?
- 為什么 ArrayList 的 elementData 加上 transient 修飾?
Set接口
24. 說(shuō)一下 HashSet 的實(shí)現(xiàn)原理?
25. HashSet如何檢查重復(fù)?HashSet是如何保證數(shù)據(jù)不可重復(fù)的?
26. HashSet與HashMap的區(qū)別
linkedllist和linkledHashSet的區(qū)別
28. 什么是鏈表
三、Map接口
27. 什么是Hash算法
20.HashMap怎么計(jì)算 key 的 hash 值的?
35. 能否使用任何類作為 Map 的 key?
27.為什么HashMap中String、Integer這樣的包裝類適合作為Key?
37. 如果使用Object作為HashMap的Key,應(yīng)該怎么辦呢?
34. HashMap是怎么解決哈希沖突的?
38. HashMap為什么不直接使用hashCode()處理后的哈希值直接作為table的下標(biāo)?
12.HashMap的實(shí)現(xiàn)原理/底層數(shù)據(jù)結(jié)構(gòu)?
13.HashMap 的長(zhǎng)度為什么是 2 的冪次方?
14.說(shuō)說(shuō)HashMap的put方法執(zhí)行流程?
15.說(shuō)說(shuō)HashMap的get方法執(zhí)行流程?
33. HashMap的擴(kuò)容操作是怎么實(shí)現(xiàn)的?
16.說(shuō)說(shuō)HashMap的resize方法執(zhí)行過(guò)程
31. 什么是紅黑樹(shù)
17.HashMap什么時(shí)候會(huì)樹(shù)化?
18.HashMap底層為什么選擇紅黑樹(shù)而不用其他樹(shù),比如二叉查找樹(shù)?
19.HashMap擴(kuò)容(加載)因子為何默認(rèn)是 0.75f?
39. HashMap 的長(zhǎng)度為什么是2的冪次方
22.HashMap多線程操作導(dǎo)致死循環(huán)問(wèn)題知道嗎?
28.說(shuō)一下Queue 與 Deque 的區(qū)別?
29.說(shuō)說(shuō)ArrayDeque 與 LinkedList 的區(qū)別?
30.說(shuō)一下 HashSet、LinkedHashSet 和 TreeSet 三者的異同?
-
HashMap在JDK1.7和JDK1.8中有哪些不同?HashMap的底層實(shí)現(xiàn)
-
什么是TreeMap 簡(jiǎn)介
-
如何決定使用 HashMap 還是 TreeMap?
-
HashMap 和 ConcurrentHashMap 的區(qū)別
-
ConcurrentHashMap 和 Hashtable 的區(qū)別?
-
ConcurrentHashMap 底層具體實(shí)現(xiàn)知道嗎?實(shí)現(xiàn)原理是什么?
四、輔助工具類 -
comparable 和 comparator的區(qū)別?
-
Collection 和 Collections 有什么區(qū)別?文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-432493.html
-
TreeMap 和 TreeSet 在排序時(shí)如何比較元素?Collections 工具類中的 sort()方法如何比較元素?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-432493.html
-
Collection 和 Collections 有什么區(qū)別?
-
TreeMap 和 TreeSet 在排序時(shí)如何比較元素?Collections 工具類中的 sort()方法如何比較元素?
到了這里,關(guān)于第二章 集合的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!