数组是保存一组基本数据类型的最优先选择的数据结构,可是在某些状况下须要保存一系列的自定义对象,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,相似于多维数组。