← 返回首页
JavaSE系列教程(三十七)
发表时间:2020-01-15 21:46:53
讲解Java集合框架之List

List(序列),序列中的元素是有序的,且允许重复。

首先,List是接口不能实例化,只能实例化List的实现类。

在List集合中,我们常用到ArrayList和LinkedList,Vector这三种List的实现类型。

1.ArrayList

ArrayList: 有顺序,可重复,可以添加 null元素。ArrayList底层通过数组实现,随着元素的增加而动态扩容。

例如:

    public static void main(String[] args) {

        List list = new ArrayList();
        list.add("grape");
        list.add("banana");
        list.add("apple");
        list.add("orange");
        list.add(null);
        list.add("watermelon");
        list.add("apple");

        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
    }

运行结果
grape
banana
apple
orange
null
watermelon
apple

由于List是由顺序的,所以每个元素都有对应的索引(下标),因此可以使用for循环遍历List里的元素。 也可以使用foreach迭代器原理遍历,如下:

    public static void main(String[] args) {

        List list = new ArrayList();
        list.add("grape");
        list.add("banana");
        list.add("apple");
        list.add("orange");
        list.add(null);
        list.add("watermelon");
        list.add("apple");

        for(Object obj : list){
            System.out.println(obj);
        }
    }
运行结果
grape
banana
apple
orange
null
watermelon
apple

2.LinkedList

ArrayList: 有顺序,可重复,可以添加 null元素。LinkedList底层通过链表来实现,随着元素的增加不断向链表的后端增加节点。

例如:

    public static void main(String[] args) {

        List list = new LinkedList();
        list.add("grape");
        list.add("banana");
        list.add("apple");
        list.add("orange");
        list.add(null);
        list.add("watermelon");
        list.add("apple");

        for(Object obj : list){
            System.out.println(obj);
        }

        ((LinkedList) list).addFirst("pear");
        ((LinkedList) list).addLast("strawberry");

        System.out.println("---------添加头尾节点后----------");
        for(Object obj : list){
            System.out.println(obj);
        }
    }

运行结果:
grape
banana
apple
orange
null
watermelon
apple
---------添加头尾节点后----------
pear
grape
banana
apple
orange
null
watermelon
apple
strawberry

通过以上代码,我们发现LinkedList有类似addFirst和addLast这样能体现链表特征的方法,也间接证明了LinkedList底层是通过链表实现的。

比较ArrayList与LinkedList的区别,恰恰就是比较顺序存储结构与离散存储结构的优缺点,总结如下: 1).ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 2).对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 3).对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

3.Vector

Vector用法与ArrayList完全相同,两者底层的数据存储都使用的Object数组实现,因为是数组实现,所以具有查找快,插入删除慢。

Vector与ArrayList最大的不同是,vector是线程安全的,在vector的大多数方法都使用synchronized关键字修饰,ArrayList是线程不安全的(可以通过Collections.synchronizedList()实现线程安全)。

4.并发包下的List

虽然Vector是线程安全的,但是Vector是从JDK1.0中给出的类,过于陈旧,所以效率低。Vector分配内存的时候需要连续的存储空间,如果数据太多,容易分配内存失败;推荐使用并发包下的CopyOnWriteArrayList替换Vector.

    CopyOnWriteArrayList list = new CopyOnWriteArrayList();
    //有顺序,可重复,可以添加空元素。
    list.add("grape");
    list.add("banana");
    list.add("apple");
    list.add("orange");
    list.add(null);
    list.add("watermelon");
    list.add("apple");

    for (int i = 0; i < list.size(); i++) {
       System.out.println(list.get(i));
    }

小结:

1.List是序列,特点是有顺序,可重复,可以添加null元素。List是接口不能实例化。

2.常用的List实现类是ArrayList/LinkedList/Vector.

3.ArrayList底层是对象数组,顺序存储结构。

4.LinkedList底层是链表,离散存储结构。

5.Vector与ArrayList用法一样,Vector是线程安全的,而ArrayList是线程不安全的。