11.1 泛型和類型安全的容器java
一、使用ArrayList至關簡單:建立一個實例,用add插入對象;而後用get()返回這些對象,此時須要使用索引,就像數組同樣,可是不須要方括號。ArrayList還有一個size()方法。使你能夠知道已經有多少元素添加了進來從而不會不當心因索引越界而引起錯誤。編程
二、應用預約義的泛型一般會很簡單。例如,要想定義用來保存Apple對象的ArrayList,你能夠聲明ArrayList<Apple>,其中尖括號括起來的是類型參數(能夠有多個),它指定了這個容器實例能夠保存的類型。經過使用泛型,就能夠在編譯期防止將錯誤類型的對象放置到容器中。數組
public class ApplesAndOrangesWithGenerics { public static void main(String[] args) { ArrayList<Apple> apples = new ArrayList<Apple>(); for(int i = 0; i < 3; i++) apples.add(new Apple()); // Compile-time error: // apples.add(new Orange()); for(int i = 0; i < apples.size(); i++) System.out.println(apples.get(i).id()); // Using foreach: for(Apple c : apples) System.out.println(c.id()); }
(1)編譯器能夠防止你將orange放置到Apple中,所以它編程了一個編譯期錯誤,而再也不是運行時錯誤。安全
(2)經過使用泛型,你不只知道編譯器將會檢查你放置到容器的對象類型,並且在使用容器中的對象時,可使用更加清晰的語法(不用再類型轉換)app
11.2 基本概念dom
一、java容器類類庫的用途是「保存對象」,並將其劃分爲兩個不一樣的概念:this
(1)Collection:一個獨立元素的序列,這些元素都服從一條或多條規則。List必須按照插入的順序保存元素,Set不能有重複元素,Queue按照排隊規則來肯定對象產生的順序(一般與插入順序相同)。code
(2)Map:一組成對的「鍵值對」對象,容許你使用鍵來查找值。ArrayList,LinkdList,TreeMap.對象
11.3添加一組元素索引
一、Arrays.asList()方法接收一個數組或是一個用逗號分隔的元素列表(使用可變參數),並將其轉化爲一個List對象。
二、Collection.addAll()方法接收一個Collection對象,以及一個數組或是一個用逗號分割的列表,將元素添加到Colleciton中。
public class AddingGroups { public static void main(String[] args) { 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. } }
11.4容器的打印
一、你必須使用Array.toString()來產生數組的可打印表示,可是打印容器無需任何幫助。
public class PrintingContainers { static Collection fill(Collection<String> collection) { collection.add("rat"); collection.add("cat"); collection.add("dog"); collection.add("dog"); return collection; } static Map fill(Map<String,String> map) { map.put("rat", "Fuzzy"); map.put("cat", "Rags"); map.put("dog", "Bosco"); map.put("dog", "Spot"); return map; } public static void main(String[] args) { System.out.println(fill(new ArrayList<String>())); System.out.println(fill(new LinkedList<String>())); System.out.println(fill(new HashSet<String>())); System.out.println(fill(new TreeSet<String>())); System.out.println(fill(new LinkedHashSet<String>())); System.out.println(fill(new HashMap<String,String>())); System.out.println(fill(new TreeMap<String,String>())); System.out.println(fill(new LinkedHashMap<String,String>())); } } /* Output: [rat, cat, dog, dog] [rat, cat, dog, dog] [dog, cat, rat] [cat, dog, rat] [rat, cat, dog] {dog=Spot, cat=Rags, rat=Fuzzy} {cat=Rags, dog=Spot, rat=Fuzzy} {rat=Fuzzy, cat=Rags, dog=Spot} *///:~
二、Collection打印出來的內容用方括號括住,每一個元素由逗號分隔。Map則用大括號括住,鍵和值由等號聯繫。
11.5 List
一、包括ArrayList和LinkedList
11.6迭代器
一、迭代器是一個對象,他的工做是遍歷並選擇序列中的對象。而客戶端程序沒必要知道或關心該序列底層的結構。
二、java的iterator只能單向異動,這個iterator只能用來:
(1)使用方法iterator()要求容器返回一個iterator。iterator將準備好返回序列的第一個元素。
(2)使用next()得到序列中下一個元素。
(3)使用hasNext()檢查序列中是否還有元素。
(4)使用remove()迭代器新近返回的元素刪除
三、iterator的真正爲例:可以將遍歷序列的操做與底層的結構分離。正因爲此,咱們有時會說:迭代統一了對容器的訪問方式。
public class CrossContainerIteration { public static void display(Iterator<Pet> it) { while(it.hasNext()) { Pet p = it.next(); System.out.print(p.id() + ":" + p + " "); } System.out.println(); } public static void main(String[] args) { ArrayList<Pet> pets = Pets.arrayList(8); LinkedList<Pet> petsLL = new LinkedList<Pet>(pets); HashSet<Pet> petsHS = new HashSet<Pet>(pets); TreeSet<Pet> petsTS = new TreeSet<Pet>(pets); display(pets.iterator()); display(petsLL.iterator()); display(petsHS.iterator()); display(petsTS.iterator()); } } /* Output: 0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 4:Pug 6:Pug 3:Mutt 1:Manx 5:Cymric 7:Manx 2:Cymric 0:Rat 5:Cymric 2:Cymric 7:Manx 1:Manx 3:Mutt 6:Pug 4:Pug 0:Rat *///:~
11.6.1ListIterator
一、它只能用於各類List類的訪問,而且能夠雙向異動。
11.7LinkedList
11.8Stack
11.9 Set
一、Set不保存重複元素。
11.10Map
public class Statistics { public static void main(String[] args) { Random rand = new Random(47); Map<Integer,Integer> m = new HashMap<Integer,Integer>(); for(int i = 0; i < 10000; i++) { // Produce a number between 0 and 20: int r = rand.nextInt(20); Integer freq = m.get(r); m.put(r, freq == null ? 1 : freq + 1); } System.out.println(m); } } /* Output: {15=497, 4=481, 19=464, 8=468, 11=531, 16=533, 18=478, 3=508, 7=471, 12=521, 17=509, 2=489, 13=506, 9=549, 6=519, 1=502, 14=477, 10=513, 5=503, 0=481} *///:~
一、Map能夠返回它的鍵的Set,它的值的Collection,或者它的鍵值對的Set。keySet()方法產生了由在Map中的全部鍵組成的Set,它在foreach語句中被用來迭代遍歷該Map.
11.11Queue
一、隊列是一個典型的先進先出的容器。
二、LinkedList提供了方法以支持隊列的行爲,而且它實現了Queue接口,所以LinkedList能夠用做Queue的一種實現。經過LinkenList向上轉型爲Queue,。
11.11.1PriorityQueue
11.12Collection和Iterator
一、Collection可使用foreach結構,從而使代碼更加清晰。
二、若是實現Collection,就必須實現iterator
11.13Foreach與迭代器
一、foreach語法主要用於數組,可是它也能夠用於任何Collection對象。
二、enrtySet()產生一個由Map.Entry的元素構成的Set,而且這個Set是一個Iterable,所以它能夠用於foreach循環。
三、不存在任何從數組到Iterable的自動轉換,你必須手工執行這種轉換。