HashMap:
資料結構簡介:
(特點:key 無序散列存放,key 唯一)
在資料處理時我們常常需要 (key, value) 的對應
先前在將List做排序的方法也是為了類似的目的
當初利用List是因為我們不需要由key去取得value的功能
只需要把所有資料依某個欄位排序全部印出即可
在這種情況底下自己建立所需資料型態的物件List會比較方便
然而有時候我們需要的是針對某個鍵值提出對應的資料
以成績單舉例好了 當我們的目的只是要列印成績單
那麼用List去做會是一個不錯的選擇
可是在List的結構底下若是我們只想得到某一學生的成績
那我們就得在List裡頭搜尋這個學生的名字然後才能得到成績
面對這種狀況另一個方法就是利用HashMap
把資料的 (key, value) 放入HashMap以後要針對特定的key取得value是非常簡單的
可以參考最下面程式碼裡面單純取得成績那段
如果HashMap裡頭有儲存資料則會傳回對應該key的value
HashMap裡沒有資料的話則會傳回 null
在HashMap裡資料的排列與key、value、加入順序都無關
HashMap有自己獨特的排列方式,像程式碼第二段的輸出結果
若是想讓資料以key值排序可以選擇用TreeMap 但效能是HashMap較佳
利用HashMap我們已經達到可以利用key值迅速取得value
但是如果我們想要印出所有資料卻又不知道姓名怎麼辦呢?
這時候只好利用HashMap的entrySet()方法取得所有資料
然後把這些資料匯入List中做處理
只要資料匯入List後就可以依照key或value排序印出了
如程式碼第三四段
在看程式碼和結果前先下個簡短的結論
如果是單純的想列印全部資料或者欄位不只兩個
那麼就建立一個自訂class的List來處理會比較方便
如同將List做排序的方法所介紹的
但如果資料只是兩欄 (key, value) 的配對
則用HashMap可以迅速取得單一key對應的資料
特性:
資料(K, V)原則上是一對一
key不能重複,若重複宣告,後者會取代前者
資料不會排序,預設是先宣告的在前面(呼叫整個 HashMap 的話)
用途:
建立對應表(轉換表),一 key 對一 value
像是學生成績表,以名字做為 key,查詢 key 可以得對應的成績 value
資料格式:1
2
3HashMap<K,V>
K: key
V: value
用法
宣告: 型別是 reference,不能存基本型別,像整數要寫 Integer 而非 int
1
2
3HashMap<String, String> hashmap = new HashMap<String, String>();
HashMap<String, String> hashmap = new HashMap<>();
HashMap<String, Integer> hashmap = new HashMap<>();新增資料: 同時給Key-Value參數,新增這筆資料到該hashMap,覆蓋之前key 對應的value 值;
1
2hashmap.put("Item 1", "Value 1");
hashmap.put("Item 1", 25);刪除資料: 根據參數Key刪掉對應的Key-Value資料
1
hashmap.remove("Item 1");
取特定key對應的值
1
hashmap.get("Item 1");
顯示整個HashMap內容
1
2
3
4System.out.println("內容:" + hashmap);
for(String Key: map.keySet()){
System.out.println(Key + " " + hashmap.get(Key));
}清空HashMap: 刪除整個HashMap內容,物件還在,但沒有東西
1
hashmap.clean();
補充:
如果想要此 map 可以1對多的話(1 key 對應多個 value)
value 的型別可以用 ArrayList
好處在value可以使用所有 ArrayList 的功能
宣告:1
HashMap<> hashmap = new HashMap<>();
每個key對應都是一個ArrayList,放數值前要先初始化:1
2hashmapmap.put("Item 1", new ArrayList<>());
hashmapmap.put("Item 2", new ArrayList<>());
新增數值:用get得到ArrayList物件,再用他的add方法新增1
2hashmap.get("Item 2").add("d");
hashmap.get("Item 2").add("e");
刪除某個key的所有value: 下次要用此key時要再次初始化1
hashmap.remove("Item 2");
刪除某個key的特定value1
hashmap.get("Item 2").remove("d");
提取輸出:也是用迭代器Iterator
,但是Map中沒有迭代器,那麼我們可也使用Collection中的,具體 方法有三種,詳見下列代碼:
1 | package map.Map; |
運行結果:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19{姓名=李四, 密碼=123, 郵箱=333@gmail.com}
{姓名=王五, 密碼=123, 郵箱=333@gmail.com}
true
false
姓名:王五
密碼:123
郵箱:333@gmail.com
姓名:王五
密碼:123
郵箱:333@gmail.com
王五
123
333@gmail.com
Hashtable
資料結構簡介:
Hashtable和HashMap的用法基本一樣,正如我們從前學過的ArrayList和Vector,還有stringBuilder和stringBuffer的區別一樣,下面只強調一點Hashtable與HashMap的另外一點不同:
HashMap中的key值和value值都可以為null,而Hashtable不可以,會出現NullPointerException
空指針異常
用法例子:
1 | public class HashtableTest { |
運行结果:1
2
3Exception in thread "main" java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:394)
at map.Map.HashtableTest.main(HashtableTest.java:15)
1 | public class HashtableTest { |
運行结果:1
{null=null, 姓名=張三}
(注意一點:
HashMap中containsKey 按照hashcode和equals查找, containsValue 根據equals查找,很好理解,因為key值具有唯一性,類似於HashSet,而value值是不唯一的,這樣就很容易理解了)
TreeMap
資料結構簡介:
TreeMap就是一種可排序的Map,按照key值進行排序,也就要求TreeMap的key值是具有可比較性的 (關於這一點,可以根據TreeSet來輔助理解)
當然,當key值不具有比較性時,會出現異常
用法例子:
下面分別給出key值是否有比較性的情況為例子:
1 | package map.Map; |
1 | 運行结果: |
從結果我們可以看出:作為key值得”a”,”b”,”c”是按照String的compareTo方法排序之後的結果
上面的例子是以String類型作為key值得,下面我們用User類型作為key值測試一下:
1 | public class TreeMapTest { |
運行结果:1
2
3Exception in thread "main" java.lang.ClassCastException: map.Map.User cannot be cast to java.lang.Comparable
at java.util.TreeMap.put(TreeMap.java:542)
at map.Map.TreeMapTest.main(TreeMapTest.java:19)
可以看出:出現了ClassCastException類型轉換異常,則一般情況下用應該使用八種封裝類或String作key值,這一點是值得注意的地方。
Reference: