Java中Map,List與Set的區別
阿新 • • 發佈:2020-07-25
首先,陣列和集合的區別:
- 陣列是大小固定的
- 集合可以儲存和運算元目不固定的一組資料,集合只能存放引用型別的的資料,不能存放基本資料型別
特性
List
- 允許重複
- 有序
- 繼承自
Connection
Set
- 不允許重複
- 無序
- 繼承自
Connection
Map
- 鍵值對
- 區別與
List
和Set
,既沒有繼承也沒有實現Connection
場景
三者各自適用什麼樣的場景?
List
- 使用索引對元素進行訪問
ArrayList
適合快速查詢,LinkedList
適合增刪元素 - 對有序有需求
Set
- 確保元素的唯一性
常用的Set
有:HashSet
、LinkedHashSet
和TreeSet
TreeSet
中的元素可以使用Comparator
或者Comparable
進行排序;LinkedHashSet
也按照元素的插入順序對它們進行儲存
Map
- 希望以鍵值對的形式存在
常用的Map
有:HashMap
、LinkedHashSet
和TreeMap
。其中HashMap
是無序的,LinkedHashSet
有序,TreeMap
可通過Comparator
或者Comparable
進行排序
另外HashTable
也可以實現鍵值對,並且相對於HashMap
是執行緒安全的,但是由於JAVA5以上ConcurrentHashMap
是執行緒安全的,但現在已經基本被HashMap
怎麼讓HashMap同步?
- synchronizeMap
- JAVA5以上
ConcurrentHashMap
是HashTable
的替代 (即執行緒安全的)
關於List<Map<String, Object>>理解
首先map<String,Object>是定義了一個Map集合變數,然後list<map<String,Object>>是定義了一個List的集合變數,是map的一個集合;map是那個list的其中一個值。
List<Map<String,Object> list=new ArrayList<Map<String,Object>>;
list.add(map);//map是list中的其中一個值。
List集合中的物件是一個Map物件,而這個Map物件的鍵是String型別,值是Object型別
package com.test; import java.util.*; public class MyTest01 { public static void main(String[] args) { List<Map<String, Object>> listMaps = new ArrayList<Map<String, Object>>(); Map<String, Object> map1 = new HashMap<String, Object>(); map1.put("1", "a"); map1.put("2", "b"); map1.put("3", "c"); listMaps.add(map1); Map<String, Object> map2 = new HashMap<String, Object>(); map2.put("11", "aa"); map2.put("22", "bb"); map2.put("33", "cc"); listMaps.add(map2); for (Map<String, Object> map : listMaps) { for (String s : map.keySet()) { System.out.print(map.get(s) + " "); } } System.out.println(); System.out.println("========================"); for (int i = 0; i < listMaps.size(); i++) { Map<String, Object> map = listMaps.get(i); Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { String string = (String) iterator.next(); System.out.println(map.get(string)); } } System.out.println("++++++++++++++++++++++++++++"); for (Map<String, Object> map : listMaps) { for (Map.Entry<String, Object> m : map.entrySet()) { System.out.print(m.getKey() + " "); System.out.println(m.getValue()); } } System.out.println("-----------------------------"); } }
List<Map<String, Object>>存放的物件問題
一、提出問題
程式碼一:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Test { public static void main(String args[]) { List<Map<String, Object>> list = new ArrayList<Map<String,Object>>(); Map<String, Object> map = new HashMap<String, Object>(); for(int i=0;i<5;i++) { // Map<String, Object> map = new HashMap<String, Object>(); map.put("a", i); map.put("b", i); list.add(map); } System.out.println(list); } }
程式碼二:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Test { public static void main(String args[]) { List<Map<String, Object>> list = new ArrayList<Map<String,Object>>(); // Map<String, Object> map = new HashMap<String, Object>(); for(int i=0;i<5;i++) { Map<String, Object> map = new HashMap<String, Object>(); map.put("a", i); map.put("b", i); list.add(map); } System.out.println(list); } }
二、給出答案
猜猜看程式碼一二執行的結果分別是啥?
沒錯,就是:
程式碼一:
[{a=4,b=4},{a=4,b=4},{a=4,b=4},{a=4,b=4},{a=4,b=4}]
程式碼二:
[{a=0,b=0},{a=1,b=1},{a=2,b=2},{a=3,b=3},{a=4,b=4}]
三、問題分析
程式碼一中,List<Map<String, Object>>裡面存放的是map物件的地址,儘管迴圈了五次,但是每次的map物件對應的都是同一個地址,即listMap裡面存放的是五個同樣的map物件。
程式碼二中,每次迴圈的時候都例項化一個新的map物件,這樣list在執行add方法的時候,每次都是存的不一樣的map物件。
可以通過debug來觀察list存放的map物件對應的id。如圖:
程式碼一:
程式碼二:
四、總結
通過上面的分析,我們可以知道,以後需要建立不同的map物件的時候,需要在迴圈裡面進行map的建立。
而不是在迴圈體外面,因為List<Map<String, Object>>指向的是map物件的地址。