Java集合之ArrayList,LinkedList,Vector

本文介绍了ArrayList和LinkedList两种数据结构的特点,对比了它们在插入和查找操作上的效率,并探讨了各自的适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




 ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
      每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组的大小。默认初始容量为10。随着ArrayList中元素的增加,它的容量也会不断的自动增长。在每次添加新的元素时,ArrayList都会检查是否需要进行扩容操作,扩容操作带来数据向新数组的重新拷贝,所以如果我们知道具体业务数据量,在构造ArrayList时可以给ArrayList指定一个初始容量,这样就会减少扩容时数据的拷贝问题。当然在添加大量元素前,应用程序也可以使用ensureCapacity操作来增加ArrayList实例的容量,这可以减少递增式再分配的数量。
      注意,ArrayList实现不是同步的。如果多个线程同时访问一个ArrayList实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步。所以为了保证同步,最好的办法是在创建时完成,以防止意外对列表进行不同步的访问:
        List list = Collections.synchronizedList(new ArrayList(...));

底层使用数组
privatetransient Object[] elementData;
      transient??为java关键字,为变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。
      这里Object[] elementData,就是我们的ArrayList容器。


  LinkedList与ArrayList一样实现List接口,只是ArrayList是List接口的大小可变数组的实现,LinkedList是List接口链表的实现。基于链表实现的方式使得LinkedList在插入和删除时更优于ArrayList,而随机访问则比ArrayList逊色些。
      LinkedList实现所有可选的列表操作,并允许所有的元素包括null。
      除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。
      此类实现 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。
      所有操作都是按照双重链接列表的需要执行的。在列表中编索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。
      同时,与ArrayList一样此实现不是同步的。

 在LinkedList中提供了两个基本属性size、header。
privatetransient Entry header = new Entry(null, null, null);privatetransientint size = 0;
      其中size表示的LinkedList的大小,header表示链表的表头,Entry为节点对象。 上面为Entry对象的源代码,Entry为LinkedList的内部类,它定义了存储的元素。该元素的前一个元素、后一个元素,这是典型的双向链表定义方式。所以LinkedList是双向链表


Vector可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。不过,Vector的大小是可以增加或者减小的,以便适应创建Vector后进行添加或者删除操作。
Vector实现List接口,继承AbstractList类,所以我们可以将其看做队列,支持相关的添加、删除、修改、遍历等功能。
Vector实现RandmoAccess接口,即提供了随机访问功能,提供提供快速访问功能。在Vector我们可以直接访问元素。
Vector 实现了Cloneable接口,支持clone()方法,可以被克隆。同时Vector是线程安全的。


以下对ArrayList和LinkedList进行效率对比:

首先插入速度对比:

public class TestTheSpeed {
	
    static long timeList(List list){   
    long start=System.currentTimeMillis();   
    String s1 = "a";
    for(int i=0;i<50000;i++)   
        list.add(0, s1);   
    return System.currentTimeMillis()-start;  
    }

	public static void main(String[] args) {
		 System.out.println("ArrayList耗时:"+timeList(new ArrayList()));   
         System.out.println("LinkedList耗时:"+timeList(new LinkedList()));   

	}

}
输出:

ArrayList耗时:266
LinkedList耗时:7


查找速度对比:

public class Test_Speed {
	static long start = System.currentTimeMillis();
	static long test (List list) {
		for(int i=0;i<50000;i++) {
			Object object = list.get(i);
		}
		long end = System.currentTimeMillis()-start;
		return end;
	}
	

	public static void main(String[] args) {
		LinkedList<String> linkedList = new LinkedList<>();
		ArrayList<String> arrayList = new ArrayList<>();
		for(int i=0;i<50000;i++) {
			linkedList.add("a");
			arrayList.add("a");
		}
		System.out.println("ArrayList索引所需要的时间"+test(arrayList));
		System.out.println("LinkedList索引所需要的时间"+test(linkedList));
		

	}

}
输出:

ArrayList索引所需要的时间17
LinkedList索引所需要的时间1460















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值