集合類:list(特定順序) set(元素不重復) queue(一端插入,一端移除) map(鍵值對)
Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
Integer[] moreInts = { 6, 7, 8, 9, 10 };
collection.addAll(Arrays.asList(moreInts));
// Runs significantly faster, but you can't
// construct a Collection this way:
Collections.addAll(collection, 11, 12, 13, 14, 15);
Collections.addAll(collection, moreInts);
// Produces a list "backed by" an array:
List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);
list.set(1, 99); // OK -- modify an element
// list.add(21); // Runtime error because the
// underlying array cannot be resized.
Collection.addAll():只能接受另一個Collection對象作參數
Collections.addAll():參數列表可變,運行速度更快
Arrays.asList():參數列表可變,直接使用方法返回是一個固定大小的數組
list
Arraylist:隨機訪問快,插入和移除慢
Linkedlist:利于插入和移除,隨機訪問慢
注意List有些方法行為依賴于equals()方法
迭代器
迭代器(一種設計模式),它可以遍歷并選擇序列中的對象,而不用關心序列底層的結構。
不用知道容器的確切類型,統一了對容器的訪問方式
iterator()
next()
hasNext()
remove()
List<Pet> pets = Pets.arrayList(12);
Iterator<Pet> it = pets.iterator();
while(it.hasNext()) {
Pet p = it.next();
System.out.print(p.id() + ":" + p + " ");
}
System.out.println();
// A simpler approach, when possible:
for(Pet p : pets)
System.out.print(p.id() + ":" + p + " ");
System.out.println();
// An Iterator can also remove elements:
it = pets.iterator();
for(int i = 0; i < 6; i++) {
it.next();
it.remove();
}
System.out.println(pets);
/* Output:
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster
[Pug, Manx, Cymric, Rat, EgyptianMau, Hamster]
*///:~
ListItertor
Iterator 只能向前移動
ListItertor 可以雙向移動,能指向當前位置的前一個和后一個索引,set()方法替換它訪問的過的后一個元素,
listIterator()方法指向開始處, 或用listIterator(n)方法一開始就指向n的索引。
List<Pet> pets = Pets.arrayList(8);
ListIterator<Pet> it = pets.listIterator();
while(it.hasNext())
System.out.print(it.next() + ", " + it.nextIndex() +
", " + it.previousIndex() + "; ");
System.out.println();
// Backwards:
while(it.hasPrevious())
System.out.print(it.previous().id() + " ");
System.out.println();
System.out.println(pets);
it = pets.listIterator(3);
while(it.hasNext()) {
it.next();
it.set(Pets.randomPet());
}
System.out.println(pets);
/* Output:
Rat, 1, 0; Manx, 2, 1; Cymric, 3, 2; Mutt, 4, 3; Pug, 5, 4; Cymric, 6, 5; Pug, 7, 6; Manx, 8, 7;
7 6 5 4 3 2 1 0
[Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Manx]
[Rat, Manx, Cymric, Cymric, Rat, EgyptianMau, Hamster, EgyptianMau]
*///:~
LinkedList
執行插入和移除效率較高,不適合隨機訪問
Set
不保存重復的元素
Set中最常被使用的是測試歸屬性,查找是set最重要的操作
Set具有與Collection完全一樣的接口,實際上Set就是Collection,只是行為不用(繼承與多態思想的典型應用:表現不同的行為)
Queue
隊列常被當作一種可靠的將對象從程序的某個區域傳輸到另一個區域的途徑,隊列在并發編程中特別重要
peek() 返回隊頭 隊列為空返回null
element() 返回隊頭 隊列為空拋出異常
poll() 移除并返回隊頭 隊列為空返回null
remove() 移除并返回隊頭 隊列為空拋出異常
PriorityQueue 優先級隊列聲明下一個彈出的元素是最需要的元素(優先級最高的),可用Comparator來設置自己的排序規則
Map
Map和Collection唯一的重疊就是Map可以使用entrySet()和values()方法來產生Collection。
Foreach與迭代器
foreach語法主要用于數組,但它也可以應用于任何Collection對象。實質是任何實現Iterable的類,都可以用foreach
這不意味數組是一個Iterable,把數組當做一個Iterable參數傳遞會導致失敗。說明不存在任何數組到Iterable的自動轉換,必須手動轉換
//: holding/ArrayIsNotIterable.java
import java.util.*;
public class ArrayIsNotIterable {
static <T> void test(Iterable<T> ib) {
for(T t : ib)
System.out.print(t + " ");
}
public static void main(String[] args) {
test(Arrays.asList(1, 2, 3));
String[] strings = { "A", "B", "C" };
// An array works in foreach, but it's not Iterable:
//! test(strings);
// You must explicitly convert it to an Iterable:
test(Arrays.asList(strings));
}
}
/* Output:
1 2 3 A B C
*///:~
*///:~
適配器方法慣用法
向Iterable類添加一個或多種使用foreach的方式
如果直接繼承這個類,并覆蓋iterator()方法。只能替換現有的方法,而不能實現選擇,因此添加一個能夠產生Iterable對象的方法,該對象能夠用于foreach語句
//: holding/MultiIterableClass.java
// Adding several Adapter Methods.
import java.util.*;
public class MultiIterableClass extends IterableClass {
public Iterable<String> reversed() {
return new Iterable<String>() {
public Iterator<String> iterator() {
return new Iterator<String>() {
int current = words.length - 1;
public boolean hasNext() { return current > -1; }
public String next() { return words[current--]; }
public void remove() { // Not implemented
throw new UnsupportedOperationException();
}
};
}
};
}
public Iterable<String> randomized() {
return new Iterable<String>() {
public Iterator<String> iterator() {
List<String> shuffled =
new ArrayList<String>(Arrays.asList(words));
Collections.shuffle(shuffled, new Random(47));
return shuffled.iterator();
}
};
}
public static void main(String[] args) {
MultiIterableClass mic = new MultiIterableClass();
for(String s : mic.reversed())
System.out.print(s + " ");
System.out.println();
for(String s : mic.randomized())
System.out.print(s + " ");
System.out.println();
for(String s : mic)
System.out.print(s + " ");
}
}
/* Output:
banana-shaped. be to Earth the know we how is that And
is banana-shaped. Earth that how the be And we know to
And that is how we know the Earth to be banana-shaped.
*///:~
注意,第二個方法random()是直接返回被打亂的list中的Iterator。
從輸出中可以看到,Collection.shuffle()方法沒有影響到原來的數組,只是打亂了shuffed中的引用,這是因為用一個Arraylist將Arrays.aslist()方法的結果包裝起來了,如果直接用Arrays.aslist()方法產生,它將會修改底層的數組。因為Arrays.aslist()方法產生list對象會使用底層數組作為其物理實現。
如果不想原來的數組被修改,那就應該在另一個容器創建一個副本。
//: holding/ModifyingArraysAsList.java
import java.util.*;
public class ModifyingArraysAsList {
public static void main(String[] args) {
Random rand = new Random(47);
Integer[] ia = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List<Integer> list1 =
new ArrayList<Integer>(Arrays.asList(ia));
System.out.println("Before shuffling: " + list1);
Collections.shuffle(list1, rand);
System.out.println("After shuffling: " + list1);
System.out.println("array: " + Arrays.toString(ia));
List<Integer> list2 = Arrays.asList(ia);
System.out.println("Before shuffling: " + list2);
Collections.shuffle(list2, rand);
System.out.println("After shuffling: " + list2);
System.out.println("array: " + Arrays.toString(ia));
}
}
/* Output:
Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After shuffling: [4, 6, 3, 1, 8, 7, 2, 5, 10, 9]
array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After shuffling: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8]
array: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8]
*///:~