[TOC]
*****
集合本質是基于某種數據結構數據容器。常見的數據結構:數組(Array)、集(Set)、隊列(Queue)、鏈表(Linkedlist)、樹(Tree)、堆(Heap)、棧(Stack)和映射(Map)等結構
## 20.1 集合概述
Java中提供了豐富的集合接口和類,它們來自于java.util包。如圖所示

## 20.2 List集合
List集合中的元素是有序的可以重復。圖20-2是一個班級集合數組,這個集合中有一些學生,這些學生是有序的,順序是他們被放到集合中的順序,可以通過序號訪問他們。這就像老師給進入班級的人分配學號,第一個報到的是“張三”,老師給他分配的是0,第二個報到的是“李四”,老師給他分配的是1,以此類推,最后一個序號應該是“學生人數-1”。

ArrayList是基于動態數組數據結構的實現,訪問元素速度優于LinkedList。
LinkedList是基于鏈表數據結構的實現。LinkedList占用的內存空間比較大,但LinkedList在批量插入或刪除數據時優于ArrayList。
### 20.2.1 常用方法
List接口繼承自Collection接口,List接口中的很多方法都繼承自Collection接口的。List接口中常用方法如下。
1. 操作元素
* 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集合繼承過來的。
2. 判斷集合中元素
* isEmpty():判斷List集合是否為空。該方法是從Collection集合繼承過來的。
* contains(Object element):判斷List集合中是否包含指定元素。該方法是從Collection集合繼承過來的。
3. 查詢指定元素索引
* indexOf(Object o):從前往后查找List集合元素,返回第一次出現指定元素的索引,如果此列表不包含該元素,則返回-1。
* lastIndexOf(Object o):從后往前查找List集合元素,返回第一次出現指定元素的索引,如果此列表不包含該元素,則返回-1。
4. 其他
* iterator():返回迭代器(Iterator)對象,迭代器對象用于遍歷集合。該方法是從Collection集合繼承過來的。
* size():返回List集合中的元素數,返回值是int類型。該方法是從Collection集合繼承過來的。
* subList(int fromIndex, int toIndex):返回List集合中指定的 fromIndex(包括 )和 toIndex(不包括)之間的元素集合,返回值為List集合。
**提示** 在Java中任何集合中存放的都是對象,即引用數據類型,基本數據類型不能放到集合中。將整數1放到集合中,這是因為這個過程中發生了自動裝箱,整數1被封裝成Integer對象1,然后再放入到集合中。
### 20.3.2 遍歷集合
集合最常用的操作之一是遍歷,遍歷就是將集合中的每一個元素取出來,進行操作或計算。List集合遍歷有三種方法:
1. 使用for循環遍歷:List集合可以使用for循環進行遍歷,for循環中有循環變量,通過循環變量可以訪問List集合中的元素。
2. 使用for-each循環遍歷:for-each循環是針對遍歷各種類型集合而推出的,筆者推薦使用這種遍歷方法。
3. 使用迭代器遍歷:Java提供了多種迭代器,List集合可以使用Iterator和ListIterator迭代器。
**示例代碼如下:**
```
~~~
//HelloWorld.java文件
package com.a51work6;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class HelloWorld {
public static void main(String[] args) {
List list = new ArrayList();
String b = "B";
// 向集合中添加元素
list.add("A");
list.add(b);
list.add("C");
list.add(b);
list.add("D");
list.add("E");
// 1.使用for循環遍歷
System.out.println("--1.使用for循環遍歷--");
for (int i = 0; i < list.size(); i++) {
System.out.printf("讀取集合元素(%d): %s \n", i, list.get(i)); ①
}
// 2.使用for-each循環遍歷
System.out.println("--2.使用for-each循環遍歷--");
for (Object item : list) { ②
String s = (String) item; ③
System.out.println("讀取集合元素: " + s);
}
// 3.使用迭代器遍歷
System.out.println("--3.使用迭代器遍歷--");
Iterator it = list.iterator(); ④
while (it.hasNext()) { ⑤
Object item = it.next(); ⑥
String s = (String) item; ⑦
System.out.println("讀取集合元素: " + s);
}
}
}
~~~
```
代碼中第一行和第三行從集合中取出的元素都是Object類型
## 20.3 Set集合
Set集合是由一串無序的,不能重復的相同類型元素構成的集合。圖20-3是一個班級的Set集合。這個Set集合中有一些學生,這些學生是無序的。

Set接口直接實現類主要是HashSet,HashSet是基于散列表數據結構的實現。
### 20.3.1 常用方法
Set接口也繼承自Collection接口,Set接口中大部分都是繼承自Collection接口,這些方法如下。
1. 操作元素
* add(Object element):在Set集合的尾部添加指定的元素。該方法是從Collection集合繼承過來的。
* remove(Object element):如果Set集合中存在指定元素,則從Set集合中移除該元素。該方法是從Collection集合繼承過來的。
* clear():從Set集合中移除所有元素。該方法是從Collection集合繼承過來的。
2. 判斷元素
* isEmpty():判斷Set集合中是否有元素,沒有返回true,有返回false。該方法是從Collection集合繼承過來的。
* contains(Object element):判斷Set集合中是否包含指定元素,包含返回true,不包含返回false。該方法是從Collection集合繼承過來的。
3. 其他
* iterator():返回迭代器(Iterator)對象,迭代器對象用于遍歷集合。該方法是從Collection集合繼承過來的。
* size():返回Set集合中的元素數,返回值是int類型。該方法是從Collection集合繼承過來的。
### 20.3.2 遍歷集合
Set集合中的元素由于沒有序號,所以不能使用for循環進行遍歷,但可以使用for-each循環和迭代器進行遍歷。事實上這兩種遍歷方法也是繼承自Collection集合,也就是說所有的Collection集合類型都有這兩種遍歷方式。
## 20.4 Map集合
Map(映射)允許按照某個鍵來訪問元素。Map集合是由兩個集合構成的,一個是鍵(key)集合,一個是值(value)集合。鍵集合是Set類型。值集合是Collection類型,可以有重復的元素。Map集合中的鍵和值是成對出現的。
圖20-4所示是Map類型的“國家代號”集合。鍵是國家代號集合,不能重復。值是國家集合,可以重復

**圖20-4 Map集合**
> **提示** Map集合更適合通過鍵快速訪問值,就像查英文字典一樣,鍵就是要查的英文單詞,而值是英文單詞的翻譯和解釋等。有一個英文單詞會對應多個翻譯和解釋,這就是map鍵與值的關系。
Map接口直接實現類主要是HashMap,HashMap是基于散列表數據結構的實現。
### 20.4.1 常用方法
Map集合中包含兩個集合(鍵和值),所以操作起來比較麻煩,Map接口提供很多方法用來管理和操作集合。主要的方法如下。
1. 操作元素
* get(Object key):返回指定鍵所對應的值;如果Map集合中不包含該鍵值對,則返回null。
* put(Object key, Object value):指定鍵值對添加到集合中。
* remove(Object key):移除鍵值對。
* clear():移除Map集合中所有鍵值對。
2. 判斷元素
* isEmpty():判斷Map集合中是否有鍵值對,沒有返回true,有返回false。
* containsKey(Object key):判斷鍵集合中是否包含指定元素,包含返回true,不包含返回false。
* containsValue(Object value):判斷值集合中是否包含指定元素,包含返回true,不包含返回false。
3. 查看集合
* keySet():返回Map中的所有鍵集合,返回值是Set類型。
* values():返回Map中的所有值集合,返回值是Collection類型。
* size():返回Map集合中鍵值對數。
### 20.4.2 遍歷集合
Map集合遍歷與List和Set集合不同,Map有兩個集合,因此遍歷時可以只遍歷值的集合,也可以只遍歷鍵的集合,也可以同時遍歷。這些遍歷過程都可以使用for-each循環和迭代器進行遍歷。
**示例代碼如下:**
```
~~~
//HelloWorld.java文件
package com.a51work6;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HelloWorld {
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(key); // 自動裝箱 ③
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);
}
}
}
~~~
```