List接口浅析

List接口为Collection直接接口。List所代表的是有序的Collection,即它用某种特定的插入顺序来维护元素顺序。用户可以对列表中每个元素的插入位置进行精确地控制,同时可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。

 

一、ArrayList

ArrayList是一个动态数组,也是我们最常用的集合。它允许任何符合规则的元素插入甚至包括 null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。

      size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。add 操作以分摊的固定时间运行,也就是说,添加 n 个元素需要 O(n) 时间(由于要考虑到扩容,所以这不只是添加元素会带来分摊固定时间开销那样简单)。

ArrayList擅长于随机访问(连续空间,下标访问),但是插入和删除效率低,需要重新排序

同时ArrayList是非同步的。

 

二、LinkedList

LinkedList的本质是双向链表,离散的,而不是连续
(01) LinkedList继承于AbstractSequentialList,并且实现了Dequeue接口。 
(02) LinkedList包含两个重要的成员:header 和 size。
  header是双向链表的表头,它是双向链表节点所对应的类Entry的实例。Entry中包含成员变量: previous, next, element。其中,previous是该节点的上一个节点,next是该节点的下一个节点,element是该节点所包含的值。 
  size是双向链表中节点的个数。

既然是双向链表,那么它的顺序访问会非常高效,而随机访问效率比较低。但是它也实现了List接口{也就是说,它实现了get(int location)、remove(int location)等“根据索引值来获取、删除节点的函数”}。

原理非常简单,它就是通过一个计数索引值来实现的。例如,当我们调用get(int location)时,首先会比较“location”和“双向链表长度的1/2”;若前者大,则从链表头开始往后查找,直到location位置;否则,从链表末尾开始先前查找,直到location位置。

LinkedList擅长插入和删除操作,而随机访问效率低,因为不需要重新排序

同时LinkedList也是非同步的

 

同步访问实现:List list = Collections.synchronizedList(new LinkedList(...));

 

三、Vector

      与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。

但是如果把方法组合使用,可能不安全,比如

Vector vector = new Vector();

public void put(String element){

if (!vector.contains(element)) 

     vector.add(element); 

}

尽管vector中的contains()方法和 add()方法都是同步的。但是组合应用时还是存在线程安全问题

解决办法:

1、在方法内使用synchronized

synchronized(this){

     if (!vector.contains(element)) 

           vector.add(element); 

}

....

2、参考单例模式的双检索方式

if (!vector.contains(element)) {

       synchronized(this){

             if (!vector.contains(element)) {

                 vector.add(element); 

              }

        }

}

 

四、Stack

Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。

boolean empty()      测试堆栈是否为空。
E   peek()       查看堆栈顶部的对象,但不从堆栈中移除它。
E   pop()       移除堆栈顶部的对象,并作为此函数的值返回该对象。
E   push(E item)       把项压入堆栈顶部。
int search(Object o)        返回对象在堆栈中的位置,以 1 为基数

测试代码:public class StackTest

1、push():把对象压入堆栈顶部。 

Stack<String> stack = null;
public StackTest(){
	stack = new Stack<String>();
	stack.push("111");
	stack.push("222");
	stack.push("333");
}

 

2、peek() :查看堆栈顶部的对象,但不从堆栈中移除它。

@Test
public void testPeek(){
		
	System.out.println("peek:"+stack.peek());
	System.out.println("------------------------------------");
	for(Iterator<String> iter = stack.iterator(); iter.hasNext(); ) {
		System.out.println(iter.next());
	}
		
}

 

3、pop()

@Test
public void testPop(){
		
	System.out.println("peek:"+stack.pop());
	System.out.println("------------------------------------");
	for(Iterator<String> iter = stack.iterator(); iter.hasNext(); ) {
		System.out.println(iter.next());
	}
		
}

 

4、seach()

@Test
public void testSeach(){

	for(Iterator<String> iter = stack.iterator(); iter.hasNext(); ) {
		System.out.println(iter.next());
	}
	System.out.println("------------------------------------");
	System.out.println("seach 333 index:"+stack.search("333"));
		
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值