1. 程式人生 > 其它 >Java基礎(6)

Java基礎(6)

技術標籤:Java基礎java字串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);
}

參考連結