Java集合基礎知識
1、為什麼要使用集合
要談程式語言引入集合的原因,就不得不談到集合與陣列的差別:
(1)長度:陣列是固定長度;集合是可變長度。
(2)元素性質:陣列的元素可以是原生資料型別,也可以是引用型別;集合的元素只能是引用型別,原生資料型別必須裝箱(jdk5.0之後有自動裝箱和拆箱功能)之後才能放入集合之中。
(3)元素型別:資料在定義之初就確定了儲存資料的型別,因此也只能儲存單一一種資料型別;集合則可以儲存不同的資料型別,雖然在實際應用中通常也只用於儲存同一型別的資料。
2、集合的繼承體系結構
Java中的集合主要集中在兩部分—— java.util包和java.util.concurrent中。其中,後者是在前者的基礎上,定義了一些實現了同步功能的集合。這裡主要關注java.util包中的集合,可以簡單地劃分為三類:List、Set和Map。對應的UML圖如下:
常用的ArrayList、LinkedList、Vector、HashSet、TreeSet都是Collection介面的具體實現類;而HashMap、TreeMap、Hashtable都是Map介面的實現類。因此,我們要講集合,必須從Collection介面和Map介面入手。
3、Collection介面
Collection介面定義了集合常見的操作:
- 新增元素:add/addAll
- 刪除元素:clear\remove/removeAll
- 判斷是否包含某元素:contains/containsAll
- 判斷集合是否為空:isEmpty
- 計算集合中元素的個數:size
- 將集合轉換為陣列:toArray
- 獲取迭代器:iterator
集合的遍歷是實際開發過程中常見的需求。這裡我們以Collection的具體實現類ArrayList為例,介紹集合的三種遍歷方法,並在集合遍歷的基礎上將上述主要的集合操作方法進行演示。具體如下:
package test; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class CollectionTest { public static void main(String[] args) { //建立集合物件 Collection<String> list = new ArrayList<String>(); //新增元素 list.add("string1"); list.add("string2"); list.add("string3"); list.add("string4"); list.add("string5"); //方法一:用增強的for迴圈遍歷集合 for(String element :list) { System.out.println(element); } //刪除元素 list.remove("string5"); System.out.println("--------------------"); //判斷集合中是否包含“string5” System.out.println(list.contains("string5")); //判斷集合是否為空 System.out.println(list.isEmpty()); //計算集合中的元素個數 int number = list.size(); System.out.println(number); System.out.println("--------------------"); //方法二:陣列遍歷法,將集合轉化為陣列,基於陣列遍歷集合 //首先,將集合轉化為陣列 Object[] array = list.toArray(); //然後,用普通的for迴圈遍歷集合(當然也可以用增強的for迴圈) for(Object element : array) { System.out.println(element); } System.out.println("--------------------"); //方法三:採用迭代器遍歷陣列 for(Iterator<String> iterator = list.iterator(); iterator.hasNext();) { String string = iterator.next(); System.out.println(string); } } }
4、List子介面
ArrayList、LinkedList、Vector等具體類並不直接實現Collection介面,而是實現Collection的子介面List。List子介面定義了Collection所不具備的功能,其特點是有序、可重複。List的特有功能包括:
- 在指定位置新增元素:add
- 刪除索引元素: remove
- 獲取制定位置的元素:get
- 修改元素:set
- 獲取迭代器:ListIterator
具體實現類及其特點簡單概括如下:
(1)ArrayList:底層資料結構是陣列,查詢快,增刪慢;
(2)Vector :底層資料結構是陣列,查詢快,增刪慢,執行緒安全,效率低;
(3)LinkedList:底層資料結構是連結串列,查詢慢,增刪快,執行緒不安全,效率高。
5、Set子介面
同樣,HashSet、TreeSet等具體類也並不直接實現Collection介面,而是實現Collection的子介面Set。Set子介面定義了Collection所不具備的功能,其特點是無序、唯一。
Set的具體實現類及其特點簡單概括如下:
(1)HashSet:底層資料結構是雜湊表;依賴hashCode()和equals()兩個方法;
(2)LinkedHashSet:底層資料結構是連結串列和雜湊表,由連結串列保證元素有序,由雜湊表保證元素唯一;
(3)TreeSet:底層資料結構是紅黑樹,保證元素排序的方式自然排序、比較器排序,根據比較的返回值是否是0來決定元素的唯一性。
6、Map介面
Map儲存的是鍵值對形式的元素。鍵唯一,值可以重複。Map的主要功能總結如下:
新增元素:put
刪除元素:clear/remove
判斷是否包含值\鍵:containsValue\ containsKey
判斷是否為空:isEmpty
獲取值\鍵的集合:get\keySet\values
獲取長度:size
在此以HashMap為例演示集合的遍歷:
package test;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class MapTest
{
public static void main(String[] args)
{
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "string1");
map.put(2, "string2");
map.put(3, "string3");
map.put(4, "string4");
map.put(5, "string5");
//遍歷方法一:以鍵找值
Set<Integer> set = map.keySet();
for(Integer key : set)
{
String value = map.get(key);
System.out.println(key + " : " + value);
}
System.out.println("--------------------");
//刪除元素
map.remove(2);
//判斷是否為空
System.out.println(map.isEmpty());
//獲取長度
System.out.println(map.size());
System.out.println("--------------------");
//遍歷方法二:鍵值對物件
Set<Entry<Integer, String>> set2 = map.entrySet();
for(Map.Entry<Integer, String> entry : set2)
{
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key + " + " + value);
}
}
}
Map的具體實現類及其特點簡單概括如下:
(1)HashMap:基於雜湊表的Map介面實現,雜湊表的作用是用來保證鍵的唯一性的,要保證唯一性必須重寫hashCode()和equals()方法;
(2)LinkedHashMap:基於雜湊表和連結列表實現,具有可預知的迭代順序,由雜湊表保證鍵的唯一性,由連結串列保證鍵的有序性
(3)TreeMap:是基於紅黑樹的Map介面的實現,保證元素排序的方式有自然排序和比較器排序。