Collection接口
├List接口
│├ArrayList
│├LinkedList
│├CopyOnWriteArrayList
└Vector
│ └Stack
└Set接口
| ├HashSet
|├LinkedHashSet
| ├TreeSet
|├CopyOrWriteArraySet
└Queue接口
| └Deque接口
| └ArrayDeque
| | blockingDeque
| | LinkedList ...
Map
├Hashtable
├HashMap
└WeakHashMap
一:Collection接口
Collection是最基本的集合接口,JavaSDK不提供直接继承自Collection的类,JavaSDK提供的类都是继承自Collection的“子接口”如List和Set。
所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。
如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:
Iteratorit = collection.iterator(); // 获得一个迭代子
while(it.hasNext()){ Objectobj = it.next(); // 得到下一个元素
}
二、List:
1、ArrayList
ArrayList和vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素。
1)Arrays.asList()的输出可作为list,但是底层表示是数组,不能调整大小,因此如果进行添加删除操作引发改变数组大小的操作会出现异常
Listlist1 = Arrays.asList(1,2,3);
list1.add(4);
抛出异常:Exceptionin thread "main" java.lang.UnsupportedOperationException
2)ListA里面有 1 2 3 ; ListB里面有 4 5 6 ; 让ListA变成 1 2 3 4 5 6
a)使用for循环
b)Arraylist.addAll(collectionc)方法
在大量数据量时使用addall方法效率快,在小数据量时,效果没有for来的好。原因如下:
ArrayList的addAll的实现为:
public boolean addAll(Collection c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacity(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
很显然,在拷贝数组时使用了
arraycopy
这个方法。这个方法是使用拷贝内存的做法,效率比遍历数组块很多。首先找到数据源然后将该段内存拷贝。当然值得注意的是,这个函数中还使用了
toArray
方法,这个方法是要遍历操作的。但是如果需要多次遍历
,
那么
addAll
还是在性能上会获取优势的
2、LinkedList
使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历。
1)快速插入,删除元素:应该使用LinkedList,插入数据时只需要记录本项的前后项即可,所以插入/移除速度较快;而ArrayList,需要数组元素移动等内存操作,比较慢。
2)快速随机访问元素:应该使用ArrayList。
对于执行效率要求高的程序,最好使用一个简单的数组(Array)来代替Vector或ArrayList。因为使用数组(Array)避免了同步、额外的方法调用和不必要的重新分配空间的操作。
3、Stack类
Vector采用数组方式存储数据,由于使用了synchronized方法(线程安全),所以性能上比ArrayList要差,Stack继承自Vector,实现一个后进先出(LIFO)的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
public classStack<T>{
privateLinkedList<T> storage = new LinkedList<T>();
public voidpush(T v) {storage.addFirst(v);}
public Tpop() {return storage.removeFirst();}
public Tpeek() {return storage.getFirst();}
publicboolean empty() {return storage.isEmpty();}
public StringtoString() {return storage.toString();}
}
下面用数组实现栈
public classStack{
privateObject[] elements;
rivate intsize = 0;
privatestatic final int Default_length = 16;
publicStack(){
elements =new Object[Default_length];
}
public voidpush(Object o){
if(elements.size = size){
elements= Arrays.copyOf(elements, 2*size + 1);
}
elements[size++]= o;
}
public Objectpop(){
if(size ==0){
returnnull;
}else{
returnelements[--size];
}
}
}
(注:1)多线程下使用需要同步方法;2)存在内存泄漏,即elements中元素不会释放。)