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的自动转换,你必须手工执行这种转换。