Java学习之List集合

问:Java中有了数组为什么还需要List集合?

答:数组长度是固定的,在日常编程中可能经常不确定会有多少个对象,如果使用数组那么一旦数量超过了数组的长度就将发生java.lang.ArrayIndexOutOfBoundsException,这个异常表示数组下标越界。

public class Hello {
	public static void main(String[] args) {
		String[] test = new String[1];
		test[0] = "123";
		test[1] = "456";
	}
}

这段代码在执行到test[1] = "456";时将报java.lang.ArrayIndexOutOfBoundsException,而集合长度是可变的,数组中存储数据类型是单一的,集合中可以存储任意类型的对象。

Java中List是一个有序的、可重复的集合,扩展Collection接口的接口,在java.util包下,提供增删改查数据的基本功能,且可以通过索引来插入替换和删除集合元素的方法。集合的出现就是为了持有对象,集合中可以存储任意类型的对象,而且长度可变。

其特点如下

  1. List允许添加重复元素

  2. List允许拥有'null'元素

  3. List支持泛型

常用的实现类有

ArrayList

LinkedList

Vector

 

一、ArrayList

ArrayList是基于数组实现的,继承自AbstractList实现了List中所有方法,该集合可以插入任何元素包括null元素,除继承过来的方法外,还提供一些方法来操作内部用来存储列表的数组的大小。

public class Hello {
	public static void main(String[] args) {
		List list = new ArrayList();
	}
}

 

Arraylist有一个初始的大小(10),该大小会随着元素的增加而增长,当然你也可以在创建的时候自定义大小

public static void main(String[] args) {
		List list = new ArrayList(20);
}

Arraylist的空间容量扩展:如果空间不够时,则取原集合大小扩展2倍和最小需求大小中较大的那个进行扩展。

ArrayList特点 1、底层使用数组数据结构 2、由于本质是数组,所以实现随机访问,而且速度较快,按照元素插入的顺序保持数据 3、删除和移动元素性能较低,因为会导致整个集合元素的移动 4、集合中的元素是可以重复的 5、有顺序 6、线程不安全的

插入,删除,查找等操作如下: 1. 插入操作需要先检查是否需要扩容数组,如果数据是插入到尾部的则可直接赋值,否则插入到中部则需要调用System.arraycopy()方法(JNI方法)移动数据腾出空间,再插入数据。 2. 删除操作直接通过System.arraycopy()操作覆盖目标值的位置 3. 修改元素值只需要在数组中直接替换。 4. 查找操作是简单的遍历查找,因此效率可能不高 。但是比LinkedList的遍历速度快。 5. 获取元素操作通过index直接返回,比较高效。

示例代码:

public static void main(String[] args) {
		List list = new ArrayList();
		//添加元素
		list.add("1");
		list.add("2");
		list.add("3");
		
		//通过下标获取元素,下标值从0开始
		list.get(0);
		
		//通过下标删除元素,下标值从0开始
		list.remove(1);
}

通常我们都需要对集合进行循环,这里给出一个小例子:

public static void main(String[] args) {
		List list = new ArrayList();
		//添加元素
		list.add("1");
		list.add("2");
		list.add("3");
		
		//循环获取元素
		for(int i = 0; i < list.size(); i++){
			System.out.println(list.get(i));
		}
}

 

二、LinkedList

LinkedList是基于链表实现的,是一种线性的存储结构,继承自AbstractSequentialList抽象类,实现了List等接口,能对它进行队列操作,LinkedList内部基于双向链表实现,允许插入任何元素,包括null。

LinkedList是一种双向链表,头结点中不存放数据,链表中任意一个存储单元都可以通过向前或者向后寻址的方式获取到其前一个存储单元和其后一个存储单元,链表的尾节点的后一个节点是链表的头结点,链表的头结点的前一个节点是链表的尾节点。

List list = new LinkedList()
 

LinkedList的特点是查询速度慢,增删快。

public static void main(String[] args) {
		List list = new LinkedList();
		list.add("123");
		list.add("456");
}
这里LinkedList中调用add添加元素实际会调用l其linkLast方法,JDK源码:
public boolean add(E e) {
        linkLast(e);
        return true;
}
该方法是在链表的末尾添加元素,也就是说,LinkedList总是把新添加的元素放在最后一个位置。

循环LinkedList的方式和ArrayList相似:

public static void main(String[] args) {
		List list = new LinkedList();
		list.add("123");
		list.add("456");
		for(int i = 0; i < list.size(); i++){
			System.out.println(list.get(i));
		}
}
 

当然你也可以使用迭代器来循环:

public static void main(String[] args) {
		List list = new LinkedList();
		list.add("123");
		list.add("456");
		
		for(Iterator iter = list.iterator(); iter.hasNext();)  {
		    System.out.println(iter.next());
		}
}
 

三、Vector

Vector 是矢量队列,它是JDK1.0版本添加的类,继承于AbstractList,实现了List, RandomAccess, Cloneable接口。

Vector 类可以实现可增长的对象数组,与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。

与ArrayList及LinkedList最大的不同是Vector中的操作是线程安全的,其大部分方法都使用了synchronized修饰来保证同步。

public static void main(String[] args) {
		List list = new Vector();
		list.add("123");
		list.add("456");
}
Vector默认的容量大小也是10,这点上和ArrayList一样,你也可以自己设置初始容量。其循环方式:
public static void main(String[] args) {
		List list = new Vector();
		list.add("123");
		list.add("456");
		for(int i = 0; i < list.size(); i++){
			System.out.println(list.get(i));
		}
}
三者的区别总结,这也是老生常谈的问题,在面试中会经常出现:

1、LinkedList是以链表形式的存储结构,允许null,提供额外的get,remove,insert方法在LinkedList的首部或尾部,不是线程安全,增删快,查询慢。

2、ArrayList是以数组形式的存储结构,允许null,不是线程安全,增删慢,查询快。

3、Vector是以数组形式的存储结构,允许null,是线程安全,效率低。

                                     

                                        

                                        你们的支持就是我们坚持下去的原因

我自建了一个JAVA学习网站:http://kfstack.com/

 

 

“种树者必培其根,种德者必养其心 --摘自阳明先生语录”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值