Java中Map,List與Set的區別

首先,數組和集合的區別:

  • 數組是大小固定的
  • 集合可以存儲和操作數目不固定的一組數據,集合只能存放引用類型的的數據,不能存放基本數據類型

特性

List

  • 允許重複
  • 有序
  • 繼承自Connection

Set

  • 不允許重複
  • 無序
  • 繼承自Connection

Map

  • 鍵值對
  • 區別與ListSet,既沒有繼承也沒有實現Connection

場景

三者各自適用什麼樣的場景?

List

  • 使用索引對元素進行訪問
    ArrayList適合快速查找,LinkedList適合增刪元素
  • 對有序有需求

Set

  • 確保元素的唯一性
    常用的Set有:HashSetLinkedHashSetTreeSet。其中,TreeSet中的元素可以使用Comparator 或者 Comparable 進行排序;LinkedHashSet也按照元素的插入順序對它們進行存儲

Map

  • 希望以鍵值對的形式存在
    常用的Map有:HashMapLinkedHashSetTreeMap。其中HashMap是無序的,LinkedHashSet有序,TreeMap可通過Comparator 或者 Comparable 進行排序
    另外HashTable也可以實現鍵值對,並且相對於HashMap是線程安全的,但是由於JAVA5以上 ConcurrentHashMap是線程安全的,但現在已經基本被HashMap取代

怎麼讓HashMap同步?

  • synchronizeMap
  • JAVA5以上 ConcurrentHashMapHashTable的替代 (即線程安全的)

關於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>>;
Map<String,Object> map=new HashMap<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對象的地址。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章