Java基礎(6)
文章目錄
- Java集合、泛型和列舉
- 參考連結
Java集合、泛型和列舉
Java集合詳解
Java 提供了集合類。集合類主要負責儲存、盛裝其他資料,因此集合類也被稱為容器類。Java 所有的集合類都位於 java.util 包下,提供了一個表示和操作物件集合的統一構架,包含大量集合介面,以及這些介面的實現類和操作它們的演算法
集合類和陣列不一樣,陣列元素既可以是基本型別的值,也可以是物件(實際上儲存的是物件的引用變數),而集合裡只能儲存物件(實際上只是儲存物件的引用變數,但通常習慣上認為集合裡儲存的是物件)
Java 集合型別分為 Collection 和 Map,它們是 Java 集合的根介面,這兩個介面又包含了一些子介面或實現類。圖 1 和圖 2 分別為 Collection 和 Map 的子介面及其實現類
下表為Java集合介面的作用
介面名稱 | 作 用 |
---|---|
Iterator 介面 | 集合的輸出介面,主要用於遍歷輸出(即迭代訪問)Collection 集合中的元素,Iterator 物件被稱之為迭代器。迭代器介面是集合介面的父介面,實現類實現 Collection 時就必須實現 Iterator 介面。 |
Collection 介面 | 是 List、Set 和 Queue 的父介面,是存放一組單值的最大介面。所謂的單值是指集合中的每個元素都是一個物件。一般很少直接使用此介面直接操作。 |
Queue 介面 | Queue 是 Java 提供的佇列實現,有點類似於 List。 |
Dueue 介面 | 是 Queue 的一個子介面,為雙向佇列。 |
List 介面 | 是最常用的介面。是有序集合,允許有相同的元素。使用 List 能夠精確地控制每個元素插入的位置,使用者能夠使用索引(元素在 List 中的位置,類似於陣列下標)來訪問 List 中的元素,與陣列類似。 |
Set 介面 | 不能包含重複的元素。 |
Map 介面 | 是存放一對值的最大介面,即介面中的每個元素都是一對,以 key➡value 的形式儲存。 |
對於 Set、List、Queue 和 Map 這 4 種集合,Java 最常用的實現類分別是 HashSet、TreeSet、ArrayList、ArrayDueue、LinkedList 和 HashMap、TreeMap 等
類名稱 | 作用 |
---|---|
HashSet | 為優化査詢速度而設計的 Set。它是基於 HashMap 實現的,HashSet 底層使用 HashMap 來儲存所有元素,實現比較簡單 |
TreeSet | 實現了 Set 介面,是一個有序的 Set,這樣就能從 Set 裡面提取一個有序序列 |
ArrayList | 一個用陣列實現的 List,能進行快速的隨機訪問,效率高而且實現了可變大小的陣列 |
ArrayDueue | 是一個基於陣列實現的雙端佇列,按“先進先出”的方式操作集合元素 |
LinkedList | 對順序訪問進行了優化,但隨機訪問的速度相對較慢。此外它還有 addFirst()、addLast()、getFirst()、getLast()、removeFirst() 和 removeLast() 等方法,能把它當成棧(Stack)或佇列(Queue)來用 |
HsahMap | 按雜湊演算法來存取鍵物件 |
TreeMap | 可以對鍵物件進行排序 |
Java Collection介面詳解
Collection 介面中常用的方法如下
方法名稱 | 說明 |
---|---|
boolean add(E e) | 向集合中新增一個元素,如果集合物件被新增操作改變了,則返回 true。E 是元素的資料型別 |
boolean addAll(Collection c) | 向集合中新增集合 c 中的所有元素,如果集合物件被新增操作改變了,則返回 true。 |
void clear() | 清除集合中的所有元素,將集合長度變為 0。 |
boolean contains(Object o) | 判斷集合中是否存在指定元素 |
boolean containsAll(Collection c) | 判斷集合中是否包含集合 c 中的所有元素 |
boolean isEmpty() | 判斷集合是否為空 |
Iteratoriterator() | 返回一個 Iterator 物件,用於遍歷集合中的元素 |
boolean remove(Object o) | 從集合中刪除一個指定元素,當集合中包含了一個或多個元素 o 時,該方法只刪除第一個符合條件的元素,該方法將返回 true。 |
boolean removeAll(Collection c) | 從集合中刪除所有在集合 c 中出現的元素(相當於把呼叫該方法的集合減去集合 c)。如果該操作改變了呼叫該方法的集合,則該方法返回 true。 |
boolean retainAll(Collection c) | 從集合中刪除集合 c 裡不包含的元素(相當於把呼叫該方法的集合變成該集合和集合 c 的交集),如果該操作改變了呼叫該方法的集合,則該方法返回 true。 |
int size() | 返回集合中元素的個數 |
Object[] toArray() | 把集合轉換為一個數組,所有的集合元素變成對應的陣列元素。 |
注意:以上方法完全來自於 Java API 文件,讀者可自行參考 API 文件來查閱這些方法的詳細資訊。讀者無需硬性記憶這些方法,可以和實際生活結合記憶。集合類就像容器,現實生活中容器的功能,就是新增物件、刪除物件、清空容器和判斷容器是否為空等,集合類為這些功能都提供了對應的方法
以下程式碼演示如何使用介面向集合中新增元素
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
list1.add("one");
list1.add("two");
list2.addAll(list1);
System.out.println("list2 集合中的元素如下:");
Iterator it = list2.iterator();
while(it.hasNext()) {
System.out.print(it.next() + "、");
}
}
Java List集合:ArrayList和LinkedList類的用法及區別
List 實現了 Collection 介面,它主要有兩個常用的實現類:ArrayList 類和 LinkedList 類
ArrayList 類
ArrayList 類實現了可變陣列的大小,儲存在內的資料稱為元素。它還提供了快速基於索引訪問元素的方式,對尾部成員的增加和刪除支援較好。使用 ArrayList 建立的集合,允許對集合中的元素進行快速的隨機訪問,不過,向 ArrayList 中插入與刪除元素的速度相對較慢
下表是ArrayList類的常用方法
方法名稱 | 說明 |
---|---|
E get(int index) | 獲取此集合中指定索引位置的元素,E 為集合中元素的資料型別 |
int index(Object o) | 返回此集合中第一次出現指定元素的索引,如果此集合不包含該元 |
素,則返回 -1
int lastIndexOf(Object o) | 返回此集合中最後一次出現指定元素的索引,如果此集合不包含該
元素,則返回 -1
E set(int index, Eelement) | 將此集合中指定索引位置的元素修改為 element 引數指定的物件。
此方法返回此集合中指定索引位置的原元素
List subList(int fromlndex, int tolndex) | 返回一個新的集合,新集合中包含 fromlndex 和 tolndex 索引之間
的所有元素。包含 fromlndex 處的元素,不包含 tolndex 索引處的
元素
一個使用示例程式碼如下
import java.util.ArrayList;
import java.util.Iterator;
public class Test12 {
public class Student {
int age;
String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public String toString() {
return this.age + " " + this.name;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList arrayList = new ArrayList();
for(int index = 0; index < 5; index++) {
arrayList.add(new Test12().new Student(23+index, "zengraoli"));
}
Iterator it = arrayList.iterator();
while(it.hasNext()) {
System.out.println(it.next().toString());
}
}
}
LinkedList類
LinkedList 類採用連結串列結構儲存物件,這種結構的優點是便於向集合中插入或者刪除元素。需要頻繁向集合中插入和刪除元素時,使用 LinkedList 類比 ArrayList 類效果高,但是 LinkedList 類隨機訪問元素的速度則相對較慢。這裡的隨機訪問是指檢索集合中特定索引位置的元素
以下為LinkList類中的方法
方法名稱 | 說明 |
---|---|
void addFirst(E e) | 將指定元素新增到此集合的開頭 |
void addLast(E e) | 將指定元素新增到此集合的末尾 |
E getFirst() | 返回此集合的第一個元素 |
E getLast() | 返回此集合的最後一個元素 |
E removeFirst() | 刪除此集合中的第一個元素 |
E removeLast() | 刪除此集合中的最後一個元素 |
使用示例程式碼如下
public class Test {
public static void main(String[] args) {
LinkedList<String> products = new LinkedList<String>(); // 建立集合物件
String p1 = new String("六角螺母");
String p2 = new String("10A 電纜線");
String p3 = new String("5M 捲尺");
String p4 = new String("4CM 原木方板");
products.add(p1); // 將 p1 物件新增到 LinkedList 集合中
products.add(p2); // 將 p2 物件新增到 LinkedList 集合中
products.add(p3); // 將 p3 物件新增到 LinkedList 集合中
products.add(p4); // 將 p4 物件新增到 LinkedList 集合中
String p5 = new String("標準資料夾小櫃");
products.addLast(p5); // 向集合的末尾新增p5物件
System.out.print("*************** 商品資訊 ***************");
System.out.println("\n目前商品有:");
for (int i = 0; i < products.size(); i++) {
System.out.print(products.get(i) + "\t");
}
System.out.println("\n第一個商品的名稱為:" + products.getFirst());
System.out.println("最後一個商品的名稱為:" + products.getLast());
products.removeLast(); // 刪除最後一個元素
System.out.println("刪除最後的元素,目前商品有:");
for (int i = 0; i < products.size(); i++) {
System.out.print(products.get(i) + "\t");
}
}
}
ArrayList 類和 LinkedList 類的區別
ArrayList 是基於動態陣列資料結構的實現,訪問元素速度優於 LinkedList。LinkedList 是基於連結串列資料結構的實現,佔用的記憶體空間比較大,但在批量插入或刪除資料時優於 ArrayList
對於快速訪問物件的需求,使用 ArrayList 實現執行效率上會比較好。需要頻繁向集合中插入和刪除元素時,使用 LinkedList 類比 ArrayList 類效果高
Java Set集合:HashSet和TreeSet類
Set 集合中不能包含重複的物件,並且最多隻允許包含一個 null 元素;Set 實現了 Collection 介面,它主要有兩個常用的實現類:HashSet 類和 TreeSet類
HashSet 類
HashSet 是 Set 介面的典型實現,大多數時候使用 Set 集合時就是使用這個實現類。HashSet 是按照 Hash 演算法來儲存集合中的元素。因此具有很好的存取和查詢效能
HashSet 具有以下特點:
- 不能保證元素的排列順序,順序可能與新增順序不同,順序也有可能發生變化。
- HashSet 不是同步的,如果多個執行緒同時訪問或修改一個 HashSet,則必須通過程式碼來保證其同步。
- 集合元素值可以是 null。
當向 HashSet 集合中存入一個元素時,HashSet 會呼叫該物件的 hashCode() 方法來得到該物件的 hashCode 值,然後根據該 hashCode 值決定該物件在 HashSet 中的儲存位置。如果有兩個元素通過 equals() 方法比較返回的結果為 true,但它們的 hashCode 不相等,HashSet 將會把它們儲存在不同的位置,依然可以新增成功
下面的程式碼演示了建立兩種不同形式的 HashSet 物件
HashSet hs = new HashSet(); // 呼叫無參的建構函式建立HashSet物件
HashSet<String> hss = new HashSet<String>(); // 建立泛型的 HashSet 集合物件
示例程式碼使用 HashSet 建立一個 Set 集合,並向該集合中新增 4 套教程
public static void main(String[] args) {
HashSet<String> courseSet = new HashSet<String>(); // 建立一個空的 Set 集合
String course1 = new String("Java入門教程");
String course2 = new String("Python基礎教程");
String course3 = new String("C語言學習教程");
String course4 = new String("Golang入門教程");
courseSet.add(course1); // 將 course1 儲存到 Set 集合中
courseSet.add(course2); // 將 course2 儲存到 Set 集合中
courseSet.add(course3); // 將 course3 儲存到 Set 集合中
courseSet.add(course4); // 將 course4 儲存到 Set 集合中
System.out.println("C語言中文網教程有:");
Iterator<String> it = courseSet.iterator();
while (it.hasNext()) {
System.out.println("《" + (String) it.next() + "》"); // 輸出 Set 集合中的元素
}
System.out.println("有" + courseSet.size() + "套精彩教程!");
}
TreeSet 類
TreeSet 類同時實現了 Set 介面和 SortedSet 介面。SortedSet 介面是 Set 介面的子介面,可以實現對集合進行自然排序,因此使用 TreeSet 類實現的 Set 介面預設情況下是自然排序的,這裡的自然排序指的是升序排序
TreeSet 只能對實現了 Comparable 介面的類物件進行排序,因為 Comparable 介面中有一個 compareTo(Object o) 方法用於比較兩個物件的大小。例如 a.compareTo(b),如果 a 和 b 相等,則該方法返回 0;如果 a 大於 b,則該方法返回大於 0 的值;如果 a 小於 b,則該方法返回小於 0 的值
實現Comparable介面類物件的比較方式
類 | 比較方式 |
---|
包裝類(BigDecimal、Biglnteger、 Byte、Double、
Float、Integer、Long 及 Short) | 按數字大小比較
Character | 按字元的 Unicode 值的數字大小比較
String | 按字串中字元的 Unicode 值的數字大小比
TreeSet 類除了實現 Collection 介面的所有方法之外,還提供了下表的方法
方法名稱 | 說明 |
---|---|
E first() | 返回此集合中的第一個元素。其中,E 表示集合中元素的資料型別 |
E last() | 返回此集合中的最後一個元素 |
E poolFirst() | 獲取並移除此集合中的第一個元素 |
E poolLast() | 獲取並移除此集合中的最後一個元素 |
SortedSet subSet(E fromElement,E toElement) | 返回一個新的集合,新集合包含原集合中 fromElement 物件與 toElement |
物件之間的所有物件。包含 fromElement 物件,不包含 toElement 物件
SortedSet headSet<E toElement〉 | 返回一個新的集合,新集合包含原集合中 toElement 物件之前的所有物件。
不包含 toElement 物件
SortedSet tailSet(E fromElement) | 返回一個新的集合,新集合包含原集合中 fromElement 物件之後的所有對
象。包含 fromElement 物件
Java Map集合詳解
Map 介面主要有兩個實現類:HashMap 類和 TreeMap 類。其中,HashMap 類按雜湊演算法來存取鍵物件,而 TreeMap 類可以對鍵物件進行排序
Map 介面中提供的常用方法如下表所示
方法名稱 | 說明 |
---|---|
void clear() | 刪除該 Map 物件中的所有 key-value 對。 |
boolean containsKey(Object key) | 查詢 Map 中是否包含指定的 key,如果包含則返回 true。 |
boolean containsValue(Object value) | 查詢 Map 中是否包含一個或多個 value,如果包含則返回 true。 |
V get(Object key) | 返回 Map 集合中指定鍵物件所對應的值。V 表示值的資料型別 |
V put(K key, V value) | 向 Map 集合中新增鍵-值對,如果當前 Map 中已有一個與該 key 相等的 key-value 對,則新的 key-value 對會覆蓋原來的 key-value 對。 |
void putAll(Map m) | 將指定 Map 中的 key-value 對複製到本 Map 中。 |
V remove(Object key) | 從 Map 集合中刪除 key 對應的鍵-值對,返回 key 對應的 value,如果該 key 不存在,則返回 null |
boolean remove(Object key, Object value) | 這是 Java 8 新增的方法,刪除指定 key、value 所對應的 key-value 對。如果從該 Map 中成功地刪除該 key-value 對,該方法返回 true,否則返回 false。 |
Set entrySet() | 返回 Map 集合中所有鍵-值對的 Set 集合,此 Set 集合中元素的資料型別為 Map.Entry |
Set keySet() | 返回 Map 集合中所有鍵物件的 Set 集合 |
boolean isEmpty() | 查詢該 Map 是否為空(即不包含任何 key-value 對),如果為空則返回 true。 |
int size() | 返回該 Map 裡 key-value 對的個數 |
Collection values() | 返回該 Map 裡所有 value 組成的 Collection |
使用程式碼如下
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
public class Test12 {
public class Student {
int age;
String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public String toString() {
return this.age + " " + this.name;
}
}
public void test2() {
HashMap hashMap = new HashMap();
for(int index = 0; index < 5; index++) {
hashMap.put(index, new Test12().new Student(23+index, "zengraoli"+index));
}
Iterator it = hashMap.keySet().iterator();
while(it.hasNext()) {
System.out.println(hashMap.get(it.next()).toString());
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new Test12().test2();
}
}
Java遍歷Map集合的四種方式
Map 集合的遍歷與 List 和 Set 集合不同。Map 有兩組值,因此遍歷時可以只遍歷值的集合,也可以只遍歷鍵的集合,也可以同時遍歷。Map 以及實現 Map 的介面類(如 HashMap、TreeMap、LinkedHashMap、Hashtable 等)都可以用以下幾種方式遍歷
在 for 迴圈中使用 entries 實現 Map 的遍歷(最常見和最常用的)
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("Java入門教程", "http://c.biancheng.net/java/");
map.put("C語言入門教程", "http://c.biancheng.net/c/");
for (Map.Entry<String, String> entry : map.entrySet()) {
String mapKey = entry.getKey();
String mapValue = entry.getValue();
System.out.println(mapKey + ":" + mapValue);
}
}
使用 for-each 迴圈遍歷 key 或者 values,一般適用於只需要 Map 中的 key 或者 value 時使用。效能上比 entrySet 較好
Map<String, String> map = new HashMap<String, String>();
map.put("Java入門教程", "http://c.biancheng.net/java/");
map.put("C語言入門教程", "http://c.biancheng.net/c/");
// 列印鍵集合
for (String key : map.keySet()) {
System.out.println(key);
}
// 列印值集合
for (String value : map.values()) {
System.out.println(value);
}
使用迭代器(Iterator)遍歷
Map<String, String> map = new HashMap<String, String>();
map.put("Java入門教程", "http://c.biancheng.net/java/");
map.put("C語言入門教程", "http://c.biancheng.net/c/");
Iterator<Entry<String, String>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Entry<String, String> entry = entries.next();
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + ":" + value);
}
通過鍵找值遍歷,這種方式的效率比較低,因為本身從鍵取值是耗時的操作
for(String key : map.keySet()){
String value = map.get(key);
System.out.println(key+":"+value);
}