Java中Map接口使用以及有關(guān)集合的面試知識(shí)點(diǎn)匯總
Map接口
存儲(chǔ)特點(diǎn)
- 以鍵(key)值(value)對(duì)的形式存儲(chǔ)
- 鍵無(wú)序、無(wú)下標(biāo)、元素不可重復(fù)
- 值無(wú)序、無(wú)下標(biāo)、元素可以重復(fù)
常用實(shí)現(xiàn)類
- HashMap
JDK1.2 底層哈希表實(shí)現(xiàn) 線程不安全,效率高 - LinkedHashMap
JDK1.2 是HashMap的子類,底層哈希表實(shí)現(xiàn) 線程不安全,效率高 - TreeMap
JDK1.2 是SortedMap的實(shí)現(xiàn)類,底層紅黑樹(shù)實(shí)現(xiàn) 線程不安全,效率高 - HashTable
JDK1.0 底層哈希表實(shí)現(xiàn) 線程安全,效率低 - Properties
JDK1.0 是HashTable的子類,底層哈希表實(shí)現(xiàn) 線程安全,效率低
創(chuàng)建方法
- 使用多態(tài)
Map<鍵的泛型,值的泛型> 集合名=new 實(shí)現(xiàn)類名<鍵的泛型,值的泛型>();
tips:一個(gè)鍵值對(duì)才是一個(gè)元素
常用方法
- 值 put(鍵,值):將一個(gè)鍵值對(duì)添加至集合末尾
如果鍵已經(jīng)存在,則進(jìn)行值的替換 - void clear():清空集合元素
- boolean containsKey(鍵):判斷集合中是否存在某個(gè)鍵
- boolean containsValue(值):判斷集合中是否存在某個(gè)值
- 值 get(鍵):獲取鍵對(duì)應(yīng)的值
- boolean isEmpty():判斷集合內(nèi)容是否為空,不能判比null值
- void putAll(Map的集合名):將指定Map集合的內(nèi)容添加至當(dāng)前集合末尾
- 值 remove(鍵):移除鍵所對(duì)應(yīng)的鍵值對(duì)
- int size():獲取集合鍵值對(duì)的個(gè)數(shù)
代碼舉例:
public class Test { public static void main(String[] args) { //數(shù)字-String 1 - 一 1 - yi Map<Integer, String> map = new HashMap<Integer, String>(); map.put(1, "一"); map.put(111, "yiyiyi"); map.put(666, "liuliuliu"); map.put(111, "一一一"); System.out.println(map.containsKey(678));//f System.out.println(map.containsValue("yiyiyi"));//t System.out.println(map.get(111)); map.remove(666); System.out.println(map.get(666)); System.out.println(map.size());//2 } }
遍歷方法
1、keySet()+get()
- 先獲取所有的鍵,再遍歷鍵得到所有的值
- Set<鍵的泛型> keySet():獲取所有的鍵存于Set集合并返回
//獲取所有鍵 Set<鍵的泛型> set=集合名.keySet(); //遍歷所有鍵 set.forEach( o-> //o就代表當(dāng)前正在被遍歷的鍵 //通過(guò)集合名.get(o)可以得到對(duì)應(yīng)的值 ); 如: Map<Integer, String> map = new HashMap<>(); map.put(123, "yiersan"); map.put(234, "ersansi"); map.put(456, "siwuliu"); map.put(999, "jiujiujiu"); Set<Integer> set=map.keySet(); set.forEach(o-> System.out.println("鍵:"+o+",值:"+map.get(o)));
2、values()
- 直接獲取所有的值
- Collection<值的泛型> values():獲取所有的值存于Collection集合并返回
Collection<值的泛型> coll = 集合名.values(); coll.forEach(v-> v就代表當(dāng)前的值); 如: Collection<String> coll = map.values(); coll.forEach(v-> System.out.println(v));
3、entrySet()
- 獲取鍵值對(duì)對(duì)象進(jìn)行遍歷
- Set< Map.Entry<鍵的泛型,值的泛型> > entrySet():獲取所有的鍵值對(duì)對(duì)象存于Set集合并返回
- Set< Map.Entry<鍵的泛型,值的泛型> > 等同于 Set<鍵值對(duì)對(duì)象>
- getKey():獲取Entry對(duì)象中的鍵
- getValue():獲取Entry對(duì)象中的值
//獲取鍵值對(duì)對(duì)象集合 Set<Map.Entry<鍵的泛型,值的泛型>> set2=集合名.entrySet(); for (Map.Entry entry : set2) { //通過(guò)entry.getKey()獲取鍵 //通過(guò)entry.getValue()獲取值 } 如: Set<Map.Entry<鍵的泛型,值的泛型>> set2=集合名.entrySet(); for (Map.Entry entry : set2) { System.out.println("鍵:"+entry.getKey()+",值:"+entry.getValue()) } System.out.println("lambda自遍歷:"); set2.forEach(entry-> System.out.println("鍵:"+entry.getKey()+",值:"+entry.getValue()));
4、自遍歷forEach
JDK8.0
集合名.forEach(new BiConsumer<鍵的泛型, 值的泛型>() { @Override public void accept(鍵的泛型 i, 值的泛型 s) { //i代表鍵 //s代表值 } }); System.out.println("lambda簡(jiǎn)化自遍歷:"); map.forEach((k,v)-> k代表鍵,v代表值); 如: map.forEach(new BiConsumer<Integer, String>() { @Override public void accept(Integer i, String s) { System.out.println("鍵:"+i+",值:"+s); } }); System.out.println("lambda簡(jiǎn)化自遍歷:"); map.forEach((k,v)-> System.out.println("鍵:"+k+",值:"+v));
不同實(shí)現(xiàn)類的使用
- HashMap可以存放null值,鍵可以存放0-1個(gè)null,值可以存放0-n個(gè)null
- LinkedHashMap可以保證存入取出順序一致
- TreeMap可以根據(jù)鍵進(jìn)行默認(rèn)的升序排序
- 不能對(duì)null進(jìn)行默認(rèn)排序
- 如果鍵為自定義類型,則必須設(shè)置排序規(guī)則,方式與TreeSet一致
- HashTable不能存放null值
- Properties鍵和值必須為String類型
- 創(chuàng)建不建議使用多態(tài)
- 不能聲明泛型
集合面試知識(shí)點(diǎn)補(bǔ)充
- Set是一個(gè)只有鍵,沒(méi)有值的Map集合
- 底層數(shù)組長(zhǎng)度為16
- 數(shù)組加載因子為75%,當(dāng)數(shù)組位使用到達(dá)75%時(shí),會(huì)以平衡二叉樹(shù)的方式進(jìn)行數(shù)組擴(kuò)容,擴(kuò)容長(zhǎng)度為原長(zhǎng)度*2,擴(kuò)容出來(lái)的每個(gè)數(shù)組長(zhǎng)度都為16
- 為什么Set或者M(jìn)ap在存放數(shù)值的時(shí)候,是從小到大的?
當(dāng)存放數(shù)值過(guò)小時(shí),整數(shù)值本身就是它的存放下標(biāo),下標(biāo)從小到大,所以值的存放也是從小到大 - 紅黑樹(shù)使用的是二分查找法,特點(diǎn)為查詢效率快
- 紅黑樹(shù):以哈希碼值為判斷標(biāo)準(zhǔn),哈希碼值比當(dāng)前元素大,往右側(cè)存儲(chǔ),哈希碼值比當(dāng)前元素小,往左側(cè)存儲(chǔ)
- 二分查找法:特點(diǎn)為一次鎖定數(shù)據(jù)的一半
- 當(dāng)哈希表的數(shù)組中某個(gè)鏈表長(zhǎng)度達(dá)到了8時(shí),會(huì)重組鏈表元素,開(kāi)啟紅黑樹(shù)
補(bǔ)充:Java Map集合面試題匯總
1、 你都知道哪些常用的Map集合?
HashMap、HashTable、LinkedHashMap、ConcurrentHashMap。
2、Collection集合接口和Map接口有什么關(guān)系?
沒(méi)關(guān)系,Collection是List、Set父接口不是Map父接口。
3、HashMap是線程安全的嗎?線程安全的Map都有哪些?性能最好的是哪個(gè)?
HashMap不是線程安全的。線程安全的有HashTable、ConcurrentHashMap、SynchronizedMap,性能最好的是ConcurrentHashMap。
4、使用HashMap有什么性能問(wèn)題嗎?
使用HashMap要注意避免集合的擴(kuò)容,它會(huì)很耗性能,根據(jù)元素的數(shù)量給它一個(gè)初始大小的值。
5、HashMap的數(shù)據(jù)結(jié)構(gòu)是怎樣的?默認(rèn)大小是多少??jī)?nèi)部是怎么擴(kuò)容的?
HashMap是數(shù)組和鏈表組成的,默認(rèn)大小為16,當(dāng)hashmap中的元素個(gè)數(shù)超過(guò)數(shù)組大小*loadFactor(默認(rèn)值為0.75)時(shí)就會(huì)把數(shù)組的大小擴(kuò)展為原來(lái)的兩倍大小,然后重新計(jì)算每個(gè)元素在數(shù)組中的位置。
6、怎么按添加順序存儲(chǔ)元素?怎么按A-Z自然順序存儲(chǔ)元素?怎么自定義排序?
按添加順序使用LinkedHashMap,按自然順序使用TreeMap,自定義排序TreeMap(Comparetor c)。
7、HashMap的鏈表結(jié)構(gòu)設(shè)計(jì)是用來(lái)解決什么問(wèn)題的?
HashMap的鏈表結(jié)構(gòu)設(shè)計(jì)是用來(lái)解決key的hash沖突問(wèn)題的。
8、HashMap的鍵、值可以為NULL嗎?HashTable呢?
HashMap的鍵值都可以為NULL,HashTable不行。
9、HashMap使用對(duì)象作為key,如果hashcode相同會(huì)怎么處理?
key的hash沖突,如果key equals一致將會(huì)覆蓋值,不一致就會(huì)將值存儲(chǔ)在key對(duì)應(yīng)的鏈表中。
10、HashMap中的get操作是什么原理?
先根據(jù)key的hashcode值找到對(duì)應(yīng)的鏈表,再循環(huán)鏈表,根據(jù)key的hash是否相同且key的==或者equals比較操作找到對(duì)應(yīng)的值。
結(jié)語(yǔ)
到此這篇關(guān)于Java中Map接口使用以及有關(guān)集合的面試知識(shí)點(diǎn)匯總的文章就介紹到這了,更多相關(guān)Java中Map接口使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql+spring+mybatis實(shí)現(xiàn)數(shù)據(jù)庫(kù)讀寫分離的代碼配置
今天小編就為大家分享一篇關(guān)于mysql+spring+mybatis實(shí)現(xiàn)數(shù)據(jù)庫(kù)讀寫分離的代碼配置,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03SpringBoot @Autowired注入為空的情況解讀
這篇文章主要介紹了SpringBoot @Autowired注入為空的情況解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03解決程序包org.springframework.test.context不存在
這篇文章主要介紹了解決程序包org.springframework.test.context不存在的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Spring關(guān)閉Tomcat Servlet容器時(shí)內(nèi)存泄漏問(wèn)題解決方案
這篇文章主要介紹了Spring關(guān)閉Tomcat Servlet容器時(shí)內(nèi)存泄漏問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10深入解析Java的Hibernate框架中的持久對(duì)象
Hibernate的持久對(duì)象在數(shù)據(jù)庫(kù)數(shù)據(jù)操作中有著重要作用,這里我們就來(lái)深入解析Java的Hibernate框架中的持久對(duì)象,首先必須從理解持久化對(duì)象的生命周期開(kāi)始:2016-07-07Nacos1.4.0 Windows10單機(jī)模式啟動(dòng)和集群?jiǎn)?dòng)過(guò)程解析
這篇文章主要介紹了Nacos1.4.0 Windows10單機(jī)模式啟動(dòng)和集群?jiǎn)?dòng),第一次使用nacos,廢話不多說(shuō),記錄下自己?jiǎn)?dòng)Nacos遇到的坑,感興趣的朋友跟隨小編一起看看吧2023-10-10用Java實(shí)現(xiàn)小球碰壁反彈的簡(jiǎn)單實(shí)例(算法十分簡(jiǎn)單)
下面小編就為大家?guī)?lái)一篇用Java實(shí)現(xiàn)小球碰壁反彈的簡(jiǎn)單實(shí)例(算法十分簡(jiǎn)單)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08SpringBoot如何優(yōu)雅的處理重復(fù)請(qǐng)求
對(duì)于一些用戶請(qǐng)求,在某些情況下是可能重復(fù)發(fā)送的,如果是查詢類操作并無(wú)大礙,但其中有些是涉及寫入操作的,一旦重復(fù)了,可能會(huì)導(dǎo)致很嚴(yán)重的后果,所以本文給大家介紹了SpringBoot優(yōu)雅的處理重復(fù)請(qǐng)求的方法,需要的朋友可以參考下2023-12-12