JAVA_HashMap運作_Set觀念補充_無序的潛藏陷阱
HashMap會去透過對應一組Key跟Value來做一個值的map存放。
key存在與不存在時的對應值回傳
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package hashmapapp; import java.util.HashMap; /** * * @author chous */ public class HashMapApp { /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here HashMap<Integer,String> map = new HashMap<Integer,String>(); map.put(5, "Five"); map.put(8, "Eight"); map.put(6, "Six"); map.put(4, "Four"); map.put(2, "Two"); String resultIsExist = map.get(4); System.out.println(resultIsExist); String resultIsNotExist = map.get(1); System.out.println(resultIsNotExist); } } |
當透過 get 方法 要回傳key的對應值時
若不存在此key則預設會返回 null
存在重複key時的對應值返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package hashmapapp; import java.util.HashMap; /** * * @author chous */ public class HashMapApp { /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here HashMap<Integer,String> map = new HashMap<Integer,String>(); map.put(5, "Five"); map.put(8, "Eight"); map.put(6, "Six"); String result = map.get(6); System.out.println(result); map.put(4, "Four"); map.put(2, "Two"); map.put(6, "Six2"); String result2 = map.get(6); System.out.println(result2); } } |
當 HashMap物件中有重複key值時
其舊有的key對應value會被覆寫
因此不建議存有重複key ,容易出錯。
HashMap 的 遍歷尋訪
寫法1. 透過 for each keySet()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package hashmapapp; import java.util.HashMap; import java.util.Map; /** * * @author chous */ public class HashMapApp { /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here HashMap<Integer,String> map = new HashMap<Integer,String>(); map.put(5, "Five"); map.put(8, "Eight"); map.put(6, "Six"); map.put(4, "Four"); map.put(2, "Two"); map.put(6, "Six2"); for(int key : map.keySet()){ System.out.println(key + ": " + map.get(key)); } } } |
寫法2. 透過for each entrySet()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package hashmapapp; import java.util.HashMap; import java.util.Map; /** * * @author chous */ public class HashMapApp { /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here HashMap<Integer,String> map = new HashMap<Integer,String>(); map.put(5, "Five"); map.put(8, "Eight"); map.put(6, "Six"); map.put(4, "Four"); map.put(2, "Two"); map.put(6, "Six2"); for(Map.Entry<Integer,String> entry: map.entrySet()){ int key = entry.getKey(); String value = entry.getValue(); System.out.println(key + ": " + value); } } } |
無序的潛藏陷阱
這裡要注意 事實上 HashMap輸出的對應結果看似是由小至大排序
但其實它是隨機生成的!!!!
所以可能你重複了執行50到100次 看起來結果都像是幫你做好排序
但事實上並沒有
預設是無任何排序處裡的
這邊來嘗試下一個範例
跟剛剛上面一樣
只不過這次以 HashMap<String , Integer>
此格式
去做值的存放
很明顯是無任何依序排列呈現的
為何會有此種現象其實就在於無論是使用剛剛遍歷尋訪的
方法1. keySet() 或者方法2. entrySet()
它們的底層皆屬於 Set
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * Returns a {@link Set} view of the keys contained in this map. * The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. If the map is modified * while an iteration over the set is in progress (except through * the iterator's own <tt>remove</tt> operation), the results of * the iteration are undefined. The set supports element removal, * which removes the corresponding mapping from the map, via the * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> * operations. It does not support the <tt>add</tt> or <tt>addAll</tt> * operations. * * @return a set view of the keys contained in this map */ public Set<K> keySet() { Set<K> ks = keySet; if (ks == null) { ks = new KeySet(); keySet = ks; } return ks; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /** * Returns a {@link Set} view of the mappings contained in this map. * The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. If the map is modified * while an iteration over the set is in progress (except through * the iterator's own <tt>remove</tt> operation, or through the * <tt>setValue</tt> operation on a map entry returned by the * iterator) the results of the iteration are undefined. The set * supports element removal, which removes the corresponding * mapping from the map, via the <tt>Iterator.remove</tt>, * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and * <tt>clear</tt> operations. It does not support the * <tt>add</tt> or <tt>addAll</tt> operations. * * @return a set view of the mappings contained in this map */ public Set<Map.Entry<K,V>> entrySet() { Set<Map.Entry<K,V>> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } |
Set 是無任何排序的 這也是它和List的最主要差異!!!
所以Set 的API官方文件也沒有提到能用index去取得特定元素的方法
這也可以說明 Set
不像 Array 和 List (LinkedList)這些資料型態是有依序擺放的!!!
留言
張貼留言