目錄
1 集合類簡介
2 List介紹及簡單使用
2.1 LinkedList介紹及簡單使用
2.2 ArrayList介紹及簡單使用
2.3 Vector介紹及簡單使用
2.3.1 Stack介紹及簡單使用
3 Set介紹
3.1 HashSet介紹及簡單使用
3.2 TreeSet介紹及簡單使用
3.3 Linked HashSet介紹
4 Map介紹及簡單使用
4.1 Hashtable介紹及簡單使用
4.2 HashMap簡單使用
4.3 WeakHashMap介紹
集合類存放於java.util包中。
集合類存放的都是對象的引用,而非對象本身,出於表達上的便利,我們稱集合中的對象就是指集合中對象的引用(reference)。
集合類型主要有3種:list(集)、set(列表)和map(映射)。
具體關系如下:
Collection
List
├LinkedList
├ArrayList
└Vector
└Stack
Set
├HashSet
├TreeSet
└Linked HashSet
Map
├Hashtable
├HashMap
└WeakHashMap
Collection是最基本的集合接口,一個Collection代表一組Object,即Collection的元素(Elements)。一些Collection允許有相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接繼承自Collection的類,Java SDK提供的類都是繼承自Collection的“子接口”如List和Set。
所有實現Collection接口的類都必須提供兩個標准的構造函數:無參數的構造函數用於創建一個空的Collection,有一個 Collection參數的構造函數用於創建一個新的Collection,這個新的Collection與傳入的Collection有相同的元素。後一個構造函數允許用戶復制一個Collection。
如何遍歷Collection中的每一個元素?不論Collection的實際類型如何,它都支持一個iterator()的方法,該方法返回一個迭代子,使用該迭代子即可逐一訪問Collection中每一個元素。典型的用法如下:
Iterator it = collection.iterator(); // 獲得一個迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一個元素
}
介紹:List是有序的Collection,使用此接口能夠精確的控制每個元素插入的位置。用戶能夠使用索引(元素在List中的位置,類似於數組下標)來訪問List中的元素,這類似於Java的數組。和下面要提到的Set不同,List允許有相同的元素。
除了具有Collection接口必備的iterator()方法外,List還提供一個listIterator()方法,返回一個 ListIterator接口,和標准的Iterator接口相比,ListIterator多了一些add()之類的方法,允許添加,刪除,設定元素, 還能向前或向後遍歷。
實現List接口的常用類有LinkedList,ArrayList,Vector和Stack。
實例:查找 List 中的最大最小值
以下實例演示了如何使用 Collections類的 max() 和 min() 方法來獲取List中最大最小值:
import java.util.*; public class Main { public static void main(String[] args) { List list = Arrays.asList("one Two three Four five six one three Four".split(" ")); System.out.println(list); System.out.println("最大值: " + Collections.max(list)); System.out.println("最小值: " + Collections.min(list)); }}
以上代碼運行輸出結果為:
[one, Two, three, Four, five, six, one, three, Four] 最大值: three 最小值: Four
介紹:LinkedList類是雙向列表,列表中的每個節點都包含了對前一個和後一個元素的引用.
LinkedList的構造函數如下
1. public LinkedList(): ——生成空的鏈表
2. public LinkedList(Collection col): 復制構造函數
實例:獲取鏈表的第一個和最後一個元素
import java.util.LinkedList; public class LinkedListTest{ public static void main(String[] args) { LinkedList<String> lList = new LinkedList<String>(); lList.add("1"); lList.add("2"); lList.add("3"); lList.add("4"); lList.add("5"); System.out.println("鏈表的第一個元素是 : " + lList.getFirst()); System.out.println("鏈表最後一個元素是 : " + lList.getLast()); } }
介紹:ArrayList就是傳說中的動態數組,換種說法,就是Array的復雜版本,它提供了如下一些好處:
動態的增加和減少元素
實現了ICollection和IList接口
靈活的設置數組的大小
實例:
ArrayList List = new ArrayList(); for( int i=0;i <10;i++ ) //給數組增加10個Int元素 List.Add(i); //..程序做一些處理 List.RemoveAt(5);//將第6個元素移除 for( int i=0;i <3;i++ ) //再增加3個元素 List.Add(i+20); Int32[] values = (Int32[])List.ToArray(typeof(Int32));//返回ArrayList包含的數組
介紹:
Vector類實現了一個動態數組。和ArrayList和相似,但是兩者是不同的:
Vector是同步訪問的。
Vector包含了許多傳統的方法,這些方法不屬於集合框架。
Vector主要用在事先不知道數組的大小,或者只是需要一個可以改變大小的數組的情況。
Vector類支持4種構造方法。
第一種構造方法創建一個默認的向量,默認大小為10:
Vector()
第二種構造方法創建指定大小的向量。
Vector(int size)
第三種構造方法創建指定大小的向量,並且增量用incr指定. 增量表示向量每次增加的元素數目。
Vector(int size,int incr)
第四中構造方法創建一個包含集合c元素的向量:
Vector(Collection c)
實例:
import java.util.*; public class VectorDemo { public static void main(String args[]) { // initial size is 3, increment is 2 Vector v = new Vector(3, 2); System.out.println("Initial size: " + v.size()); System.out.println("Initial capacity: " + v.capacity()); v.addElement(new Integer(1)); v.addElement(new Integer(2)); v.addElement(new Integer(3)); v.addElement(new Integer(4)); System.out.println("Capacity after four additions: " + v.capacity()); v.addElement(new Double(5.45)); System.out.println("Current capacity: " + v.capacity()); v.addElement(new Double(6.08)); v.addElement(new Integer(7)); System.out.println("Current capacity: " + v.capacity()); v.addElement(new Float(9.4)); v.addElement(new Integer(10)); System.out.println("Current capacity: " + v.capacity()); v.addElement(new Integer(11)); v.addElement(new Integer(12)); System.out.println("First element: " + (Integer)v.firstElement()); System.out.println("Last element: " + (Integer)v.lastElement()); if(v.contains(new Integer(3))) System.out.println("Vector contains 3."); // enumerate the elements in the vector. Enumeration vEnum = v.elements(); System.out.println("\nElements in vector:"); while(vEnum.hasMoreElements()) System.out.print(vEnum.nextElement() + " "); System.out.println(); }}
以上實例編譯運行結果如下:
Initial size: 0
Initial capacity: 3
Capacity after four additions: 5
Current capacity: 5
Current capacity: 7
Current capacity: 9
First element: 1Last element: 12Vector contains 3. Elements in vector:1 2 3 4 5.45 6.08 7 9.4 10 11 12
2.3.1 Stack介紹及簡單使用
介紹:
棧是Vector的一個子類,它實現了一個標准的後進先出的棧。
堆棧只定義了默認構造函數,用來創建一個空棧。 堆棧除了包括由Vector定義的所有方法,也定義了自己的一些方法。
Stack()
除了由Vector定義的所有方法,自己也定義了一些方法:
序號
方法描述
1
boolean empty()
測試堆棧是否為空。
2
Object peek( )
查看堆棧頂部的對象,但不從堆棧中移除它。
3
Object pop( )
移除堆棧頂部的對象,並作為此函數的值返回該對象。
4
Object push(Object element)
把項壓入堆棧頂部。
5
int search(Object element)
返回對象在堆棧中的位置,以 1 為基數。
實例:
下面的程序說明這個集合所支持的幾種方法
import java.util.*; public class StackDemo { static void showpush(Stack st, int a) { st.push(new Integer(a)); System.out.println("push(" + a + ")"); System.out.println("stack: " + st); } static void showpop(Stack st) { System.out.print("pop -> "); Integer a = (Integer) st.pop(); System.out.println(a); System.out.println("stack: " + st); } public static void main(String args[]) { Stack st = new Stack(); System.out.println("stack: " + st); showpush(st, 42); showpush(st, 66); showpush(st, 99); showpop(st); showpop(st); showpop(st); try { showpop(st); } catch (EmptyStackException e) { System.out.println("empty stack"); } }}
以上實例編譯運行結果如下:
stack: [ ] push(42) stack: [42] push(66) stack: [42, 66] push(99) stack: [42, 66, 99] pop -> 99 stack: [42, 66] pop -> 66 stack: [42] pop -> 42 stack: [ ] pop -> empty stack
介紹:
Set不保存重復的元素。Set中最常被使用的是測試歸屬性,你可以很容易的詢問某個對象是否在某個Set中。Set具有與Collection完全一樣的接口,因此沒有任何額外的功能。實際上Set就是Collection,只是行為不同。
實現了Set接口的主要有HashSet、TreeSet、LinkedHashSet這幾個共同點就是每個相同的項只保存一份。他們也有不同點,區別如下:
介紹:
HashSet使用的是相當復雜的方式來存儲元素的,使用HashSet能夠最快的獲取集合中的元素,效率非常高(以空間換時間)。會根據hashcode和equals來龐端是否是同一個對象,如果hashcode一樣,並且equals返回true,則是同一個對象,不能重復存放。
實例:
package com.set; import java.util.HashSet; import java.util.Set; class Student{ int id; public Student(int id) { this.id = id; } @Override public String toString() { return this.id+""; } @Override public int hashCode() { return this.id; } @Override public boolean equals(Object obj) { if (obj instanceof Student){ Student stu = (Student) obj; if (stu.id == this.id) return true; } return false; } } public class HashSetTest { public static void main(String[] args) { Set<Student> set = new HashSet<Student>(); Student s1 = new Student(1); Student s2 = new Student(1); Student s3 = new Student(2); set.add(s1); set.add(s2); set.add(s3); for (Student s : set) { System.out.println(s); } } }
正如上例所示,重寫了hashCode()和equals()方法來區分同意對象後,就不能存放同以對象了。如果注釋這兩個方法,則所有Student對象視為不同對象,都可以存放。
介紹:
TreeSet也不能存放重復對象,但是TreeSet會自動排序,如果存放的對象不能排序則會報錯,所以存放的對象必須指定排序規則。排序規則包括自然排序和客戶排序。
①自然排序:TreeSet要添加哪個對象就在哪個對象類上面實現java.lang.Comparable接口,並且重寫comparaTo()方法,返回0則表示是同一個對象,否則為不同對象。
②客戶排序:建立一個第三方類並實現java.util.Comparator接口。並重寫方法。定義集合形式為TreeSet ts = new TreeSet(new 第三方類());
實例:
下面一個例子用TreeSet存放自然排序的對象:
package com.set; import java.util.Set; import java.util.TreeSet; class Student1 implements Comparable<Student1>{ int id; public Student1(int id) { this.id = id; } @Override public String toString() { return this.id+""; } @Override public int hashCode() { return this.id; } @Override public boolean equals(Object obj) { if (obj instanceof Student1){ Student1 stu = (Student1) obj; if (stu.id == this.id) return true; } return false; } public int compareTo(Student1 o) { return (this.id-o.id); } } public class TreeSetTest { public static void main(String[] args) { Set<Student1> set = new TreeSet<Student1>(); Student1 s1 = new Student1(5); Student1 s2 = new Student1(1); Student1 s3 = new Student1(2); Student1 s4 = new Student1(4); Student1 s5 = new Student1(3); set.add(s1); set.add(s2); set.add(s3); set.add(s4); set.add(s5); for (Student1 s : set) { System.out.println(s); } } }
輸出結果為:
1 2 3 4 5
介紹:LinkedHashSet按照插入順序保存對象,同時還保存了HashSet的查詢速度。
介紹:
Map接口中鍵和值一一映射. 可以通過鍵來獲取值。
給定一個鍵和一個值,你可以將該值存儲在一個Map對象. 之後,你可以通過鍵來訪問對應的值。
當訪問的值不存在的時候,方法就會拋出一個NoSuchElementException異常.
當對象的類型和Map裡元素類型不兼容的時候,就會拋出一個 ClassCastException異常。
當在不允許使用Null對象的Map中使用Null對象,會拋出一個NullPointerException 異常。
當嘗試修改一個只讀的Map時,會拋出一個UnsupportedOperationException異常。
序號
方法描述
1
void clear( )
從此映射中移除所有映射關系(可選操作)。
2
boolean containsKey(Object k)
如果此映射包含指定鍵的映射關系,則返回 true。
3
boolean containsValue(Object v)
如果此映射將一個或多個鍵映射到指定值,則返回 true。
4
Set entrySet( )
返回此映射中包含的映射關系的 Set 視圖。
5
boolean equals(Object obj)
比較指定的對象與此映射是否相等。
6
Object get(Object k)
返回指定鍵所映射的值;如果此映射不包含該鍵的映射關系,則返回 null。
7
int hashCode( )
返回此映射的哈希碼值。
8
boolean isEmpty( )
如果此映射未包含鍵-值映射關系,則返回 true。
9
Set keySet( )
返回此映射中包含的鍵的 Set 視圖。
10
Object put(Object k, Object v)
將指定的值與此映射中的指定鍵關聯(可選操作)。
11
void putAll(Map m)
從指定映射中將所有映射關系復制到此映射中(可選操作)。
12
Object remove(Object k)
如果存在一個鍵的映射關系,則將其從此映射中移除(可選操作)。
13
int size( )
返回此映射中的鍵-值映射關系數。
14
Collection values( )
返回此映射中包含的值的 Collection 視圖。
實例:
import java.util.*; public class CollectionsDemo { public static void main(String[] args) { Map m1 = new HashMap(); m1.put("Zara", "8"); m1.put("Mahnaz", "31"); m1.put("Ayan", "12"); m1.put("Daisy", "14"); System.out.println(); System.out.println(" Map Elements"); System.out.print("\t" + m1); }}
以上實例編譯運行結果如下:
Map Elements {Mahnaz=31, Ayan=12, Daisy=14, Zara=8}
介紹:
Hashtable是原始的java.util的一部分, 是一個Dictionary具體的實現 。
然而,Java 2 重構的Hashtable實現了Map接口,因此,Hashtable現在集成到了集合框架中。它和HashMap類很相似,但是它支持同步。
像HashMap一樣,Hashtable在哈希表中存儲鍵/值對。當使用一個哈希表,要指定用作鍵的對象,以及要鏈接到該鍵的值。
然後,該鍵經過哈希處理,所得到的散列碼被用作存儲在該表中值的索引。
實例:
下面的程序說明這個數據結構支持的幾個方法:
import java.util.*; public class HashTableDemo { public static void main(String args[]) { // Create a hash map Hashtable balance = new Hashtable(); Enumeration names; String str; double bal; balance.put("Zara", new Double(3434.34)); balance.put("Mahnaz", new Double(123.22)); balance.put("Ayan", new Double(1378.00)); balance.put("Daisy", new Double(99.22)); balance.put("Qadir", new Double(-19.08)); // Show all balances in hash table. names = balance.keys(); while(names.hasMoreElements()) { str = (String) names.nextElement(); System.out.println(str + ": " + balance.get(str)); } System.out.println(); // Deposit 1,000 into Zara's account bal = ((Double)balance.get("Zara")).doubleValue(); balance.put("Zara", new Double(bal+1000)); System.out.println("Zara's new balance: " + balance.get("Zara")); }}
以上實例編譯運行結果如下:
Qadir: -19.08Zara: 3434.34Mahnaz: 123.22Daisy: 99.22Ayan: 1378.0 Zara's new balance: 4434.34
介紹:以下實例演示了如何使用 Collection 類的 iterator() 方法來遍歷集合:
import java.util.*; public class Main { public static void main(String[] args) { HashMap< String, String> hMap = new HashMap< String, String>(); hMap.put("1", "1st"); hMap.put("2", "2nd"); hMap.put("3", "3rd"); Collection cl = hMap.values(); Iterator itr = cl.iterator(); while (itr.hasNext()) { System.out.println(itr.next()); } }}
以上代碼運行輸出結果為:
3rd 2nd 1st
介紹:
WeakHashMap實現了Map接口,是HashMap的一種實現,他使用弱引用作為內部數據的存儲方案,WeakHashMap可以作為簡單緩存表的解決方案,當系統內存不夠的時候,垃圾收集器會自動的清除沒有在其他任何地方被引用的鍵值對。
如果需要用一張很大的HashMap作為緩存表,那麼可以考慮使用WeakHashMap,當鍵值不存在的時候添加到表中,存在即取出其值。
WeakHashMap weakMap = new WeakHashMap<Integer, byte[]>(); for(int i = 0; i < 10000; i++){ Integer ii = new Integer(i); weakMap.put(ii, new byte[i]); }
參考資料:
1、Java Vector 類
2、Java 實例 - HashMap遍歷
3、Java Hashtable 接口
4、Java Map 接口
5、Java Stack 類
6、Java集合類詳解
7、java筆記四:Set接口