數組是保存一組基本數據類型的最優先選擇的數據結構,可是在某些狀況下須要保存一系列的自定義對象,Java提供了一套至關完整的容器類來結局這個問題(List、Set、Queue、Map)。這些容器均有本身的特點,如Set能夠保證保存的對象互異,Map保存k-v對(關聯數組)。容器類能夠自動調整本身的容量,所以在編程時,不用擔憂容器的容量問題(前提是你有足夠大的內存)。java
容器類在默認狀況下是接收Object類的,換種說法,就是接收任何類型的類。泛型的做用就是在建立一個容器對象時,指定該容器對象接收的對象類型。例如:編程
package test; import java.util.ArrayList; /* * ArrayList不使用泛型,add()接收任何非法的類型。 * orange能夠添加到apples中,編譯時無錯誤,運行時出現「類型轉換錯誤」。 * */ public class AppleOrangeWithoutGeneric { public static void main(String[] args){ ArrayList apples = new ArrayList(); Apple apple = new Apple(); Orange orange = new Orange(); apples.add(apple); apples.add(orange); for (int i = 0; i<apples.size(); i++){ ((Apple)apples.get(i)).eat(); } } } class Apple{ public void eat(){} } class Orange{ public void eat(){ } }
在編譯時,以上示例代碼並沒有問題,可是會出現運行時錯誤,由於強制類型轉換是非法的。數組
比較安全一些的作法是在定義apples時指定該ArrayList只能接受Apple的對象。例如:安全
package test; import java.util.ArrayList; public class AppleOrangeWithGeneric { public static void main(String[] args){ ArrayList<Apple> apples = new ArrayList<Apple>(); Apple apple = new Apple(); Orange orange = new Orange(); apples.add(apple);
//Compile error //apples.add(orange); for (int i = 0; i<apples.size(); i++){ ((Apple)apples.get(i)).eat(); } } } class Apple{ public void eat(){} } class Orange{ public void eat(){ } }
List有兩種基本的類型,LinkedList在隨機訪問方面先對比較慢,ArrayList適用於隨機訪問,可是中間插入和移除元素時比較慢。數據結構
基本操做:add() get() equals() remove() retainAll() subList() containsAll() toArray()app
迭代器能夠提升代碼複用程度。迭代器是一個隊形,他的工做原理是遍歷並選擇序列中的對象,使用迭代器能夠不用關心List的類型;dom
1) 使用iterator()方法返回一個Iterator,準備返回序列中的第一個元素。優化
2)使用next()方法得到當前位置的下一個元素。對象
3)使用hasNext()方法判斷是否到達序列尾部。blog
4)使用remove()方法將當前元素刪除。
迭代器統一了對容器的訪問方式,使得遍歷序列的操做與程序底層的結構分離。
使用方法較ArrayList更豐富,移除和插入效率更高。LinkedList添加了可使其用做棧、隊列或雙端隊列的方法。
先進後出,一種使用了LinkedList的實現:
package test; import java.util.LinkedList; public class StackTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Stack<String> stack = new Stack<String>(); stack.push("str1"); stack.push("str2"); System.out.println(stack.pop()); System.out.println(stack.pop()); } } class Stack<T>{ private LinkedList<T> storage = new LinkedList<T>(); public void push(T t){storage.addFirst(t);} public T pop() {return storage.removeFirst();} public boolean isEmpty() {return storage.isEmpty();} public String toString() {return storage.toString();} }
Set不會保存重複的元素。Set最常被使用的場景是判斷歸屬性,使用Set能夠輕易地查詢某個對象是否存在某個Set中。HashSet專門對快速查找進行了優化。Set具備與Collection徹底同樣的接口,除此以外無其餘功能。
package test; import java.util.*; public class SetOfInteger { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Random rand = new Random(1); Set<Integer> set = new HashSet<Integer>(); for(int i = 0; i<1000; i++){ set.add(rand.nextInt(30)); } System.out.println(set.toString()); } }
輸出
[15, 8, 23, 16, 7, 22, 9, 21, 6, 1, 29, 14, 24, 4, 19, 26, 11, 18, 3, 12, 27, 17, 2, 13, 28, 20, 25, 10, 5, 0]
即便在代碼中修改rand的seed值,輸出仍然不發生變化,但輸出的順序無規律可言。這是由於set在內部對所存儲的值進行了散列。TreeSet將元素維護在一顆紅黑樹中,所以想要得到有序的元素的話,最好使用TreeSet或者LinkedHaskSet:
package test; import java.util.*; public class TreeSetOfInteger { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Random rand = new Random(1); Set<Integer> set = new TreeSet<Integer>(); for(int i = 0; i<1000; i++){ set.add(rand.nextInt(30)); } System.out.println(set.toString()); } }
輸出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
隊列,典型的先進先出容器。LinkedList實現了Queue的接口,能夠向上轉型爲Queue。offer()方法將一個元素添加到隊尾。peek()和element()方法都在不移除的狀況下,返回隊頭,可是peek()在隊爲空時,返回null,後者在一樣狀況下返回nosuchelementexception。
存儲k-v對。以下面例子,key爲某個數字,value是使用random產生的該數字的次數。
package test; import java.util.*; public class Statistics { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Random rand = new Random(100); Map<Integer,Integer> map = new HashMap<Integer,Integer>(); for(int i = 0; i<1000;i++){ int tmp = rand.nextInt(10); Integer count = map.get(tmp); map.put(tmp, count==null ? 1 : ++count); } System.out.println(map.toString()); } }
輸出:
{2=96, 4=92, 9=102, 8=108, 6=99, 1=95, 3=105, 7=95, 5=99, 0=109}
Map中的元素也能夠是Map,相似於多維數組。