物件容器——集合
集合的概述
Java 中提供了豐富的集合介面和類,它們來自於 java.util 包。如同 15-1 所示是 Java 主要的集合介面和類,從圖中可見 Java 集合型別分為:Collection 和 Map,Collection 子 介面有:Set、Queue 和 List 等介面。每一種集合介面描述了一種資料結構。 本章重點介紹 List、Set 和 Map 介面,因此圖 15-1 中只列出了這三個介面的具體實現 類,事實上 Queue 也有具體實現類,由於很少使用,這裡不再贅述,讀者感興趣可以自 己查詢 API 文件。
提示 學習Java中的集合,首先從兩大介面入手,重點掌握List、Set和Map三個介面,熟悉 這些介面中提供的方法。然後再熟悉這些介面的實現類,並瞭解不同實現類之間的區 別。
List集合
List 集合中的元素是有序的,可以重複出現。圖 15-2 是一個班級集合陣列,這個集合 中有一些學生,這些學生是有序的,順序是他們被放到集合中的順序,可以通過序號訪問 他們。這就像老師給進入班級的人分配學號,第一個報到的是“張三”,老師給他分配的 是 0,第二個報到的是“李四”,老師給他分配的是 1,以此類推,最後一個序號應該是 “學生人數-1”。
提示 List集合關心的元素是否有序,而不關心是否重複,請大家記住這個原則。例如,圖152所示的班級集合中就有兩個“張三”。
List 介面的實現類有:ArrayList 和 LinkedList。ArrayList 是基於動態陣列資料結構的實 現,LinkedList 是基於連結串列資料結構的實現。ArrayList 訪問元素速優於 LinkedList,LinkedList 佔用的記憶體空間比較大,但 LinkedList 在批量插入或刪除資料時優於 ArrayList。 不同的結構對應於不同的演算法,有的考慮節省佔用空間,有的考慮提高執行效率,對 於程式設計師而言,它們就像是“熊掌”和“魚肉”,不可兼得!提高執行速度往往是以犧牲 空間為代價的,而節省佔用空間往往是以犧牲執行速度為代價的。
常用方法
List 介面繼承自 Collection 介面,List 介面中的很多方法都繼承自 Collection 介面的。 List 介面中常用方法如下。
-
操作元素
-
get(int index):返回 List 集合中指定位置的元素。
-
set(int index, Object element):用指定元素替換 List 集合中指定位置的元素。
-
add(Object element):在 List 集合的尾部新增指定的元素。該方法是從 Collection 集合繼承過了的。
-
add(int index, Object element):在 List 集合的指定位置插入指定元素。
-
remove(int index):移除 List 集合中指定位置的元素。
-
remove(Object element):如果 List 集合中存在指定元素,則從 List 集合中移除第 一次出現的指定元素。該方法是從 Collection 集合繼承過了的。
-
clear():從 List 集合中移除所有元素。該方法是從 Collection 集合繼承過了的。
-
-
判斷元素
-
isEmpty():判斷 List 集合中是否有元素,沒有返回 true,有返回 false。該方法是 從 Collection 集合繼承過了的。
-
-
-
查詢元素
-
indexOf(Object o):從前往後查詢 List 集合元素,返回第一次出現指定元素的索 引,如果此列表不包含該元素,則返回-1。
-
lastIndexOf(Object o):從後往前查詢 List 集合元素,返回第一次出現指定元素的 索引,如果此列表不包含該元素,則返回-1。
-
-
其他
-
iterator():返回迭代器(Iterator)物件,迭代器物件用於遍歷集合。該方法是從 Collection 集合繼承下來的。
-
size():返回 List 集合中的元素數,返回值是 int 型別。該方法是從 Collection 集 合繼承下來的。
-
subList(int fromIndex, int toIndex):返回 List 集合中指定的 fromIndex(包括 )和 toIndex(不包括)之間的元素集合,返回值 List 集合。
-
注意:在Java中任何集合中存放的都是物件,即引用資料型別,為什麼我們在集合框架當中能夠存入基本資料型別,因為在存入資料和取出資料的時候,基本資料型別存在一個自動的裝箱和解裝箱的過程
遍歷集合
集合最常用的操作之一是遍歷,遍歷就是將集合中的每一個元素取出來,進行操作或 計算。List 集合遍歷有三種方法:
-
使用 for 迴圈遍歷:List 集合可以使用 for 迴圈進行遍歷,for 迴圈中有迴圈變數, 通過迴圈變數可以訪問 List 集合中的元素。
-
使用 for-each 迴圈遍歷:for-each 迴圈是針對遍歷各種型別集合而推出的,筆者 推薦使用這種遍歷方法。
-
使用迭代器遍歷:Java提供了多種迭代器,List集合可以使用Iterator和 ListIterator 迭代器。
( 1Interator it = list.iterator() 2.when(it.hasnext()){ Object item = it.next();} )
Set集合
Set 集合是由一串無序的,不能重複的相同型別元素構成的集合。圖 15-3 是一個班級 的 Set 集合。這個 Set 集合中有一些學生,這些學生是無序的,不能通過類似於 List 集合 的序號訪問,而且不能有重複的同學。
提示 List集合中的元素是有序的、可重複的,而Set集合中的元素是無序的、不能重複的。 List集合強調的是有序,Set集合強調的是不重複。當不考慮順序,且沒有重複元素時, Set集合和List集合可以互相替換的。
常用方法
Set 介面也繼承自 Collection 介面,Set 介面中大部分都是繼承自 Collection 介面,這 些方法如下
-
操作元素
-
add(Object element):在 Set 集合的尾部新增指定的元素。該方法是從 Collection 集合繼承過了的。
-
remove(Object element):如果 Set 集合中存在指定元素,該方法是從 Collection 集合繼承過了的。
-
clear():從 Set 集合中移除所有元素。該方法是從 Collection 集合繼承過了的。
-
-
判斷元素
-
isEmpty():判斷 Set 集合中是否有元素,沒有返回 true,有返回 false。該方法是 從 Collection 集合繼承過了的。
-
contains(Object element):判斷 Set 集合中是否包含指定元素,包含返回 true, 不包含返回 false。該方法是從 Collection 集合繼承過了的。
-
-
其他
-
iterator():返回迭代器(Iterator)物件,迭代器物件用於遍歷集合。該方法是從 Collection 集合繼承下來的。
-
size():返回 Set 集合中的元素數,返回值是 int 型別。該方法是從 Collection 集 合繼承下來的。
-
遍歷元素
Set 集合中的元素由於沒有序號,所以不能使用 for 迴圈進行遍歷,但可以使用 foreach 迴圈和迭代器進行遍歷。事實上這兩種遍歷方法也是繼承自 Collection 集合,也就是 說所有的 Collection 集合型別都有這兩種遍歷方式。
-
foreach
-
Iterator
Map集合
Map(對映)集合表示一種非常複雜的集合,允許按照某個鍵來訪問元素。Map 集合 是由兩個集合構成的,一個是鍵(key)集合,一個是值(value)集合。鍵集合是 Set 類 型,因此不能有重複的元素。而值集合是 Collection 型別,可以有重複的元素。Map 集合 中的鍵和值是成對出現的。 圖 15-4 所示是 Map 型別的“國家代號”集合。鍵是國家代號集合,不能重複。值是 國家集合,可以重複。
Map 介面直接實現類主要是 HashMap,HashMap 是基散列表資料結構的實現
常用方法
Map 集合中包含兩個集合(鍵和值),所以操作起來比較麻煩,Map 介面提供很多方 法用來管理和操作集合。主要的方法如下。
-
操作元素
-
get(Object key):返回指定鍵所對於的值;如果 Map 集合中不包含該鍵值對,則 返回 null。
-
put(Object key, Object value):指定鍵值對新增到集合中。
-
remove(Object key):移除鍵值對。
-
clear():移除 Map 集合中所有鍵值對。
-
-
判斷元素
-
isEmpty():判斷 Map 集合中是否有鍵值對,沒有返回 true,有返回 false。
-
containsKey(Object key):判斷鍵集合中是否包含指定元素,包含返回 true,不包 含返回 false。
-
containsValue(Object value):判斷值集合中是否包含指定元素,包含返回 true, 不包含返回 false
-
-
檢視集合
-
keySet():返回 Map 中的所有鍵集合,返回值是 Set 型別。
-
values():返回 Map 中的所有值集合,返回值是 Collection 型別。
-
size():返回 Map 集合中鍵值對數。
-
遍歷集合
Map 集合遍歷與 List 和 Set 集合不同,Map 有兩個集合,因此遍歷過程可以只遍歷 值的集合,也可以只遍歷鍵的集合,也可以同時遍歷。這些遍歷過程都可以使用 for-each 迴圈和迭代器進行遍歷。
public class TestMap { public static void main(String[] args) { Map map = new HashMap(); map.put(102, "張三"); map.put(105, "李四"); map.put(109, "王五"); map.put(110, "董六"); map.put(111, "李四"); // 1.使用for-each迴圈遍歷 System.out.println("--1.使用for-each迴圈遍歷--"); // 獲得鍵集合 Set keys = map.keySet(); for (Object key : keys) { int ikey = (Integer) key; // 自動拆箱 String value = (String) map.get(ikey); // 自動裝箱 System.out.printf("key=%d - value=%s \n", ikey, value); } // 2.使用迭代器遍歷 System.out.println("--2.使用迭代器遍歷--"); // 獲得值集合 Collection values = map.values(); // 遍歷值集合 Iterator it = values.iterator(); while (it.hasNext()) { Object item = it.next(); String s = (String) item; System.out.println("值集合元素: " + s); } } }
//--1.使用for-each迴圈遍歷--
//key=102 - value=張三
//key=105 - value=李四
//key=109 - value=王五
//key=110 - value=董六
//key=111 - value=李四
//--2.使用迭代器遍歷--
//值集合元素: 張三
//值集合元素: 李四
//值集合元素: 王五
//值集合元素: 董六
//值集合元素: 李四