List集合实现类之ArrayList、Vector和LinkedList

List集合的实现类有3种,分别是ArrayList、Vector和LinkedList,下面我将对这3个实现类的区别进行详细讲解。

1)ArrayList
ArrayList继承自AbstractList而实现了List,它是最常用的List实现类,内部是通过数组实现的,所以插入或者删除元素时,需要对数组进行复制、移动、代价比较高,因此,它适合随机查找和遍历,不适合插入和删除。

public class ArrayListTest {
	public static void main(String[] args) {
		List<Integer> list = new ArrayList<Integer>();
		list.add(5);
		list.add(6);
		list.add(7);
		list.add(8);
		list.add(9);
		list.add(10);
		
		// 通过迭代器遍历
		Iterator<Integer> iterator = list.iterator();
		while (iterator.hasNext()) {
			System.out.print(iterator.next() + " ");
		}
		System.out.println("\n--------------------------");
		
		// for循环遍历
		for (Integer integer : list) {
			System.out.print(integer + " ");
		}
		System.out.println("\n--------------------------");
		
		// 随机访问,通过list.get(i)获得索引值去遍历。
		for (int i = 0; i < list.size(); i++) {
			System.out.print(list.get(i) + " ");
		}
	}
}

ArrayList之所以线程不安全,从其add()方法就可以看出:

public boolean add(E e) {
	ensureCapacityInternal(size + 1);  //确保容量是否充足
	elementData[size++] = e;           //将元素添加至数组
	return true;
}

从底层源码可以看出,add()添加元素的时候是分两步走的:

(1)elementData[size] = e;           

(2)size++;

     假设有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停(线程A仅仅完成了步骤1,Size没有自增),线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,此时 Size 仍然等于 0 ,所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。 那好,现在我们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。 

2)LinkedList
LinkedList底层采用链表结构进行数据存储,很适合数据的动态插入和删除(add()和remove()方法),随机访问和遍历速度比较慢。需要注意的是:LinkedList提供了List接口中未定义的方法,专门用于操作表头和表尾元素,所以可以当作堆栈、队列和双向队列使用。

public class LinkedListTest {
	public static void main(String[] args) {
		List<Integer> list = new LinkedList<Integer>();
		list.add(5);
		list.add(6);
		list.add(7);
		list.add(8);
		list.add(9);
		list.add(10);

		// 通过迭代器遍历
		Iterator<Integer> iterator = list.iterator();
		while (iterator.hasNext()) {
			System.out.print(iterator.next() + " ");
		}
		System.out.println("\n--------------------------");
		
		// for循环遍历
		for (Integer integer : list) {
			System.out.print(integer + " ");
		}
		System.out.println("\n--------------------------");
		
		// 随机访问,通过list.get(i)获得索引值去遍历,不建议
		for (int i = 0; i < list.size(); i++) {
			System.out.print(list.get(i) + " ");
		}

	}
}

3)Vector
Vector底层也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。


public class VectorTest {
	public static void main(String[] args) {
		Vector<Integer> vec = new Vector<Integer>();
		vec.add(5);
		vec.add(6);
		vec.add(7);
		vec.add(8);
		vec.add(9);
		vec.add(10);

		// 通过迭代器遍历
		Integer value = null;
		for (int i = 0; i < vec.size(); i++) {
			value = (Integer) vec.get(i);
			System.out.println(value + " ");
		}
		System.out.println("\n--------------------------");

		// for循环遍历
		Integer value2 = null;
		for (Integer integ : vec) {
			value2 = integ;
			System.out.println(value2 + " ");
		}
		System.out.println("\n--------------------------");

		// 随机访问,通过索引值去遍历(Vector实现了RandomAccess接口,支持通过索引值去随机访问元素)
		Integer value3 = null;
		for (int i = 0; i < vec.size(); i++) {
			value3 = (Integer) vec.get(i);
			System.out.println(value3 + " ");
		}
		System.out.println("\n--------------------------");

		// Enumeration遍历
		Integer value4 = null;
		Enumeration enu = vec.elements();
		while (enu.hasMoreElements()) {
			value4 = (Integer) enu.nextElement();
			System.out.println(value4 + " ");
		}

	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值