在java.util包中的Arrays和Collections类中都有很多实用方法,可以在一个Collection中添加一组元素。Arrays.asList()方法接受一个数组或是一个用逗号分隔的元素列表(使用可变参数),并将其转换为一个List集合。Collections.addAll()方法接受一个Collection对象,以及一个数组或是一个用逗号分隔的列表,将元素添加到Collection中。
package com.huangfei.thinking.holding; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; public class AddingGroups { public static void main(String[] args) { /** * Collection的构造器可以接受另一个Collection,用它来将自身初始化,因此你可以使用Arrays.asList()来为这个构造器产生输入。 * 但是,Collection.addAll()方法运行起来要快得多,而且构建一个不包含元素的Collection,然后调用Collection.addAll() * 这种方式很方便,因此它是首选方式。 */ 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)); /** * Collection.addAll()成员方法只能接受另一个Collection对象作为参数,因此它不如Arrays.asList() * 和Collections.addAll()灵活,这两个方法使用的都是可变参数列表。 */ Collections.addAll(collection, 11, 12, 13, 14, 15); Collections.addAll(collection, moreInts); /** * 你可以直接使用Arrays.asList()的输出,将其当作List,但是这种情况下,其底层表示的是数组,因此不能调整尺寸。如果你试图用add() * 或delete()方法在这种列表中添加或删除元素,就有可能会引发去改变数组尺寸的尝试,因此你将在运行时获得“UnsupportedOperationException” * (不支持的操作)的错误。 */ List<Integer> list = Arrays.asList(16, 17, 18,19, 20); list.set(1, 99); //list.add(21); } }Arrays.asList()方法的限制是它对所产生的List的类型做出了最理想的假设,而并没有注意你对它会赋予什么样的类型。有时就会引发问题:
package com.huangfei.thinkinginjava.holding; import java.util.*; class Snow {} class Powder extends Snow {} class Light extends Powder {} class Heavy extends Powder {} class Crusty extends Snow {} class Slush extends Snow {} public class AsListInference { public static void main(String[] args) { List<Snow> snow1 = Arrays.asList(new Crusty(), new Slush(), new Powder()); /** * 当试图创建snow2时,Arrays.asList()中只有Power类型,因此它会创建List<Powder>而不是List<Snow>。 */ // List<Snow> snow2 = Arrays.asList(new Light(), new Heavy()); /** * Collections.addAll()工作的很好,因为它从第一个参数中了解到了目标类型是什么。 */ List<Snow> snow3 = new ArrayList<Snow>(); Collections.addAll(snow3, new Light(), new Heavy()); /** * 可以在Arrays.asList()中间插入一条“线索”,以告诉编译器对于由Arrays.asList()产生的List类型,实际的目标类型应该是什么,这 * 称为显示类型参数说明。 */ List<Snow> snow4 = Arrays.<Snow>asList(new Light(), new Heavy()); } }创建一个空的LinkedList,通过使用ListIterator,将若干个Integer插入这个List,插入时,总是将它们插入到List的中间。
package com.huangfei.thinkinginjava.holding; import java.util.LinkedList; import java.util.ListIterator; public class MiddleInsertion { public static void main(String[] args) { LinkedList<Integer> list = new LinkedList<Integer>(); ListIterator<Integer> lt = list.listIterator(); for (int i = 1; i <= 10; i++) { lt.add(i); if(i % 2 == 0) lt.previous(); } System.out.println(list); } } //output [1, 3, 5, 7, 9, 10, 8, 6, 4, 2]尽管已经有了java.util.Stack,但是由于Java设计者在创建时使用了继承的方式(继承List),使得java.util.Stack具有其他不需要的方法,所以通过LinkedList实现自定义Stack会是一种比较好的选择。
package com.huangfei.thinkinginjava.holding; import java.util.LinkedList; /** * 用LinkedList实现栈 * @author huangfei * * @param <T> */ public class Stack<T> { private LinkedList<T> storage = new LinkedList<T>(); public void push(T t){ storage.addFirst(t); } public T peek(){ return storage.peek(); } public T pop(){ return storage.removeFirst(); } public boolean isEmpty(){ return storage.isEmpty(); } public String toString(){ return storage.toString(); } }LinkedList提供了方法以支持队列的行为,并且它实现了Queue接口,因此LinkedList可以用作Queue的一种实现。
PriorityQueue是所谓的优先级队列,比如构建了一个消息系统,某些消息比其他消息更重要,因而应该更快地得到处理,那么它们何时得到处理就与它们何时到达无关。
当在PriorityQueue调用offer()方法来插入一个对象时,这个对象会在队列中被排序,默认的排序将使用对象在队列中的自然顺序,但是可以通过提供Comparator来修改这个顺序。
package com.huangfei.thinkinginjava.holding; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.PriorityQueue; import java.util.Queue; import java.util.Random; public class PriorityQueueDemo { private static void printQueue(Queue queue){ while(queue.peek() != null) System.out.print(queue.remove() + " "); System.out.println(); } public static void main(String[] args) { PriorityQueue<Integer> priorityQueue = new PriorityQueue<Integer>(); Random rand = new Random(47); for (int i = 0; i < 10; i++) { priorityQueue.offer(rand.nextInt(i + 10)); } /** * 在PriorityQueue中,重复是允许的,最小的值拥有最高的优先级(如果是String,空格也可以算作值,并且比字母的优先级高)。 */ printQueue(priorityQueue); List<Integer> ints = Arrays.asList(25, 22, 20, 18, 14, 9, 3, 1, 1, 2, 3, 9, 14, 18, 21, 23, 25); priorityQueue = new PriorityQueue<Integer>(ints); printQueue(priorityQueue); /** * 通过传入Collections.reverseOrder()使得PriorityQueue产生反序的效果 */ priorityQueue = new PriorityQueue<Integer>(ints.size(), Collections.reverseOrder()); priorityQueue.addAll(ints); printQueue(priorityQueue); PriorityQueue<Dummy> queue = new PriorityQueue<Dummy>(); System.out.println("Adding 1st instance..."); queue.offer(new Dummy()); System.out.println("Adding 2nd instance..."); /** * 会报java.lang.ClassCastException: com.huangfei.thinkinginjava.holding.Dummy * cannot be cast to java.lang.Comparable * Integer、String已经内建了自然排序,如果想在PriorityQueue中使用自己的类,就必须包含额外的功能以产生自然排序, * 或者必须提供自己的Comparator。 */ queue.offer(new Dummy()); } } class Dummy { } //output 0 1 1 1 1 1 3 5 8 14 1 1 2 3 3 9 9 14 14 18 18 20 21 22 23 25 25 25 25 23 22 21 20 18 18 14 14 9 9 3 3 2 1 1 Adding 1st instance... Adding 2nd instance... Exception in thread "main" java.lang.ClassCastException: com.huangfei.thinkinginjava.holding.Dummy cannot be cast to java.lang.Comparable at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:633) at java.util.PriorityQueue.siftUp(PriorityQueue.java:629) at java.util.PriorityQueue.offer(PriorityQueue.java:329) at com.huangfei.thinkinginjava.holding.PriorityQueueDemo.main(PriorityQueueDemo.java:52)