Map
今天的主要內(nèi)容
Map接口概述
-
Map集合的兩種遍歷方式
通過(guò)鍵找值keySet
-
通過(guò)鍵值對(duì)對(duì)象獲取鍵和值
- 涉及到Map.Entry的認(rèn)識(shí)
-
HashMap
- 自定義對(duì)象必須重寫(xiě)equals和hashCode方法
LinkedHashMap
-
TreeMap
- 統(tǒng)計(jì)字符串中每個(gè)字符出現(xiàn)的次數(shù)
-
HashMap和Hashtable的區(qū)別
線程安全方面
存儲(chǔ)鍵值對(duì)的數(shù)據(jù)類(lèi)型方面
一拒炎、集合框架(Map集合概述和特點(diǎn))
-
Map接口概述
-
查看API可以知道:
將鍵映射到值的對(duì)象( maps keys to values)
一個(gè)映射不能包含重復(fù)的鍵(A map cannot contain duplicate keys)
每個(gè)鍵最多只能映射到一個(gè)值( each key can map to at most one value.)
-
-
Map接口和Collection接口的不同
Map是雙列的,Collection是單列的
Map的鍵唯一,Collection的子體系Set是唯一的
Map集合的數(shù)據(jù)結(jié)構(gòu)值針對(duì)鍵有效公条,跟值無(wú)關(guān);Collection集合的數(shù)據(jù)結(jié)構(gòu)是針對(duì)元素有效
二墓阀、集合框架(Map集合的功能概述)
-
A:Map集合的功能概述
-
a:添加功能
-
V put(K key,V value):添加元素。
如果鍵是第一次存儲(chǔ)粗恢,就直接存儲(chǔ)元素洲守,返回null
如果鍵不是第一次存在魄缚,就用值把以前的值替換掉,返回以前的值
相同的鍵不存儲(chǔ)喜滨,值覆蓋
-
-
b:刪除功能
void clear():移除所有的鍵值對(duì)元素
V remove(Object key):根據(jù)鍵刪除鍵值對(duì)元素捉捅,并把值返回
-
c:判斷功能
boolean containsKey(Object key):判斷集合是否包含指定的鍵
boolean containsValue(Object value):判斷集合是否包含指定的值
boolean isEmpty():判斷集合是否為空
-
d:獲取功能
Set<Map.Entry<K,V>> entrySet():
V get(Object key):根據(jù)鍵獲取值
Set<K> keySet():獲取集合中所有鍵的集合
Collection<V> values():獲取集合中所有值的集合
-
e:長(zhǎng)度功能
- int size():返回集合中的鍵值對(duì)的個(gè)數(shù)
-
-
測(cè)試程序
public class TestMap { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); //添加功能 System.out.println("====V put(K key,V value):添加元素.===="); testPut(map); //刪除功能 System.out.println("====V remove(Object key):===="); testRemove(map); //判斷功能 System.out.println("==============判斷功能=============="); testBoolean(map); System.out.println(" ==========e:長(zhǎng)度功能 int size()=========="); testSize(map); } public static void testPut(Map<String,Integer> map) { /* a:添加功能 V put(K key,V value):添加元素。 * 如果鍵是第一次存儲(chǔ)虽风,就直接存儲(chǔ)元素棒口,返回null * 如果鍵不是第一次存在,就用值把以前的值替換掉辜膝,返回以前的值 */ Integer i1 = map.put("小王", 21); Integer i2 = map.put("小李", 22); Integer i3 = map.put("小王", 23); Integer i4 = map.put("小花", 24); Integer i5 = map.put("小明", 25); System.out.println(map); System.out.println(i1); System.out.println(i2); System.out.println(i3); System.out.println(i4); System.out.println(i5); /* * 在JDK1.8中輸出結(jié)果為: * ------------------------------- * ====V put(K key,V value):添加元素.==== {小李=22, 小明=25, 小王=23, 小花=24} null //返回null表示值沒(méi)有被覆蓋 null 21 //鍵相等无牵,值覆蓋,返回被覆蓋的值 null null * ------------------------------- * */ } public static void testRemove(Map<String,Integer> map) { /* * b:刪除功能 * void clear():移除所有的鍵值對(duì)元素 * V remove(Object key):根據(jù)鍵刪除鍵值對(duì)元素厂抖,并把值返回 */ Integer i1 = map.remove("小王"); Integer i2 = map.remove("小李"); System.out.println(i1); System.out.println(i2); System.out.println("刪除后茎毁,集合中元素有:"); System.out.println(map); /* * 在JDK1.8中輸出結(jié)果為: * --------------------------------- * ====V remove(Object key):==== 23 22 刪除后,集合中元素有: {小明=25, 小花=24} --------------------------------- * */ } public static void testBoolean(Map<String,Integer> map) { /* * c:判斷功能 * * boolean containsKey(Object key):判斷集合是否包含指定的鍵 * boolean containsValue(Object value):判斷集合是否包含指定的值 * boolean isEmpty():判斷集合是否為空 */ System.out.println("Map集合是否為空?" + map.isEmpty()); System.out.println("Map集合是否包含指定的鍵“小花七蜘? " + map.containsKey("小花")); System.out.println("Map集合是否包含指定的值:28 " + map.containsValue(28)); /* * 在JDK1.8中輸出結(jié)果為: * --------------------------------------- * ==============判斷功能============== Map集合是否為空谭溉?false Map集合是否包含指定的鍵“小花? true Map集合是否包含指定的值:28 false --------------------------------------- * */ } public static void testSize(Map<String,Integer> map) { System.out.println("Map中鍵值對(duì)個(gè)數(shù)為: " + map.size()); /* * 在JDK1.8中輸出結(jié)果為: * --------------------------------------- * ==========e:長(zhǎng)度功能 int size()========== Map中鍵值對(duì)個(gè)數(shù)為: 2 --------------------------------------- * */ } }
三橡卤、集合框架(Map集合的遍歷之鍵找值)
-
鍵找值思路:
-
獲取所有鍵的集合
- Set<K> keySet()——返回所有鍵的集合
-
遍歷鍵的集合扮念,獲取到每一個(gè)鍵
- Set集合中的iterator方法
-
根據(jù)鍵找值
- V get(Object key)
-
-
程序——Map集合的遍歷之鍵找值
public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); map.put("小王", 21); map.put("小李", 22); map.put("小花", 24); map.put("小明", 25); //獲取所有鍵 Set<String> set = map.keySet(); //獲取迭代器 Iterator<String> i = set.iterator(); //遍歷輸出所有鍵 while(i.hasNext()) { String key = i.next(); System.out.println("key = " + key + " value = " + map.get(key)); } //增強(qiáng)的for循壞輸出鍵值對(duì) /* for(String key : map.keySet()) { System.out.println("key = " + key + " value = " + map.get(key)); }*/ }
四、集合框架(Map集合的遍歷之鍵值對(duì)對(duì)象找鍵和值)
-
鍵值對(duì)對(duì)象找鍵和值思路:碧库、
-
獲取所有鍵值對(duì)對(duì)象的集合——entrySet方法返回Map.Entry類(lèi)型
- 將所有的Map.Entry對(duì)象放在Set集合中
-
* 遍歷鍵值對(duì)對(duì)象的集合柜与,獲取到每一個(gè)鍵值對(duì)對(duì)象
* Set接口中的iterator方法遍歷出每一個(gè)Map.Entry對(duì)象
* 根據(jù)鍵值對(duì)對(duì)象找鍵和值
* 利用Map.Entry接口中的getKey()和getValue方法獲取鍵和值
- 案例演示
-
Map集合的遍歷之鍵值對(duì)對(duì)象找鍵和值
public class TestIterator_3 { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); map.put("小王", 21); map.put("小李", 22); map.put("小花", 24); map.put("小明", 25); /*//Map.Entry說(shuō)明Entry是Map的內(nèi)部接口 //將鍵和值封裝成Entry對(duì)象,并存儲(chǔ)在Set集合中 Set<Map.Entry<String,Integer>> entrySet = map.entrySet(); //獲取每一個(gè)對(duì)象 Iterator<Map.Entry<String, Integer>> i = entrySet.iterator(); while(i.hasNext()) { Map.Entry<String,Integer> me = i.next(); System.out.println("key = " + me.getKey() + "value = " + me.getValue()); }*/ for(Map.Entry<String, Integer> e : map.entrySet()) { System.out.println("key = " + e.getKey() + "value = " + e.getValue()); } } } /* * 在JDK1.8中輸出結(jié)果為: * ----------------------- * key = 小李value = 22 key = 小明value = 25 key = 小王value = 21 key = 小花value = 24 ------------------------ * */
-
五嵌灰、HashMap
-
類(lèi)似于HashSet對(duì)鍵唯一的要求
- 在自定義類(lèi)型的時(shí)候旅挤,一定要重寫(xiě)HashCode和equals方法
六、LinkedHashMap
- 鏈表實(shí)現(xiàn):可保證怎么存就怎么取
七伞鲫、TreeMap
-
自定義對(duì)象必須實(shí)現(xiàn)Comparable接口或者Comparator接口
自定義對(duì)象若實(shí)現(xiàn)Comparable接口粘茄,則必須重寫(xiě)compareTo方法
自定義對(duì)象若實(shí)現(xiàn)Comparator接口,則必須重寫(xiě)compare方法
八秕脓、集合框架(統(tǒng)計(jì)字符串中每個(gè)字符出現(xiàn)的次數(shù))
需求:統(tǒng)計(jì)字符串中每個(gè)字符出現(xiàn)的次數(shù)
-
分析
- 從鍵盤(pán)獲取字符串輸入柒瓣,將字符串轉(zhuǎn)換為字符數(shù)組
- 創(chuàng)建HashMap集合,將字符串中的字符作為key存入到HashMap中
- 當(dāng)該字符包含在HashMap中時(shí)吠架,則增加value
- 遍歷HashMap輸出字符串中每一個(gè)字符出現(xiàn)的次數(shù)
-
程序
public class TestMap_2 { public static void main(String[] args) { //1. 從鍵盤(pán)獲取字符串輸入芙贫,將字符串轉(zhuǎn)換為字符數(shù)組 Scanner input = new Scanner(System.in); System.out.println("請(qǐng)輸入要統(tǒng)計(jì)的字符串"); String string = input.nextLine(); char[] charArr = string.toCharArray(); //2. 創(chuàng)建HashMap集合,將字符串中的字符作為key存入到HashMap中 HashMap<Character, Integer> hashMap = new HashMap<>(); //3. 當(dāng)該字符包含在HashMap中時(shí)傍药,則增加value for(char c : charArr) { /* if(hashMap.containsKey(c)) { //增加value hashMap.put(c,hashMap.get(c) + 1); } else { hashMap.put(c,1); } */ //上段代碼也等價(jià)于 hashMap.put(c, hashMap.containsKey(c) ? hashMap.get(c) + 1 : 1); } //4. 遍歷HashMap輸出字符串中每一個(gè)字符出現(xiàn)的次數(shù) //在這兒我們使用通過(guò)鍵值對(duì)象獲取鍵和值 Set<Map.Entry<Character, Integer>> set = hashMap.entrySet(); //獲取set的迭代器 Iterator<Map.Entry<Character, Integer>> iterator = set.iterator(); //遍歷輸出鍵和值 while(iterator.hasNext()) { //獲取Entry對(duì)象 Entry<Character, Integer> entry = iterator.next(); System.out.println(entry.getKey() + "出現(xiàn)的次數(shù)為:" + entry.getValue()); } } } /* * 在JDK1.8中輸出結(jié)果為: * ---------------- * 請(qǐng)輸入要統(tǒng)計(jì)的字符串 aaaabbbbbcc a出現(xiàn)的次數(shù)為:4 b出現(xiàn)的次數(shù)為:5 c出現(xiàn)的次數(shù)為:2 ---------------- * */
九磺平、集合框架(HashMap和Hashtable的區(qū)別)
-
A:面試題
-
HashMap和Hashtable相同點(diǎn)
- 底層實(shí)現(xiàn)都是哈希算法,都是雙列集合
-
HashMap和Hashtable的區(qū)別
Hashtable是JDK1.0版本出現(xiàn)的,是線程安全的,效率低,HashMap是JDK1.2版本出現(xiàn)的,是線程不安全的,效率高
Hashtable不可以存儲(chǔ)null鍵和null值,HashMap可以存儲(chǔ)null鍵和null值
-
十拐辽、集合框架(Collections工具類(lèi)的概述和常見(jiàn)方法講解)
-
A:Collections類(lèi)概述
- 針對(duì)集合操作 的工具類(lèi)
-
B:Collections成員方法
public static <T> void sort(List<T> list) public static <T> int binarySearch(List<?> list,T key) public static <T> T max(Collection<?> coll) public static void reverse(List<?> list) public static void shuffle(List<?> list)
十一拣挪、集合框架(模擬斗地主洗牌和發(fā)牌)
模擬斗地主洗牌和發(fā)牌
-
程序
//買(mǎi)一副牌 String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"}; String[] color = {"方片","梅花","紅桃","黑桃"}; HashMap<Integer, String> hm = new HashMap<>(); //存儲(chǔ)索引和撲克牌 ArrayList<Integer> list = new ArrayList<>(); //存儲(chǔ)索引 int index = 0; //索引的開(kāi)始值 for(String s1 : num) { for(String s2 : color) { hm.put(index, s2.concat(s1)); //將索引和撲克牌添加到HashMap中 list.add(index); //將索引添加到ArrayList集合中 index++; } } hm.put(index, "小王"); list.add(index); index++; hm.put(index, "大王"); list.add(index); //洗牌 Collections.shuffle(list); //發(fā)牌 TreeSet<Integer> gaojin = new TreeSet<>(); TreeSet<Integer> longwu = new TreeSet<>(); TreeSet<Integer> me = new TreeSet<>(); TreeSet<Integer> dipai = new TreeSet<>(); for(int i = 0; i < list.size(); i++) { if(i >= list.size() - 3) { dipai.add(list.get(i)); //將list集合中的索引添加到TreeSet集合中會(huì)自動(dòng)排序 }else if(i % 3 == 0) { gaojin.add(list.get(i)); }else if(i % 3 == 1) { longwu.add(list.get(i)); }else { me.add(list.get(i)); } } //看牌 lookPoker("高進(jìn)", gaojin, hm); lookPoker("龍五", longwu, hm); lookPoker("馮佳", me, hm); lookPoker("底牌", dipai, hm);
}
public static void lookPoker(String name,TreeSet<Integer> ts,HashMap<Integer, String> hm) {
System.out.print(name + "的牌是:");
for (Integer index : ts) {
System.out.print(hm.get(index) + " ");
}
System.out.println();
}