List、ArrayList、LinkedList、Vector

List是Collection的一个子接口,ArrayList、LinkedList、Vector是List的实现类。

它们的共同特点都是:有序、可重复。

它们拥有Collection集合的所有方法,也有一些自己特有的方法。

因为是有序的,即集合中的元素是有下标的,所以可以通过元素下标来操作元素。

如下:

(下标从0开始!)

  • void add(int index, E element):在指定位置添加元素;

  • E get(int index):获取指定位置的元素;

  • E remove(int index):移除指定位置的元素;

  • E set(int index,E element):将指定位置的元素替换成别的值;

1.List

List是一个接口,不能实例化对象,需要借助其实现子类。

由于List是有序的,所以在迭代器遍历和for增强遍历的基础上,还可以使用下标遍历。

package com.dh.list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class List01 {

    public static void main(String[] args) {
        //List是一个接口,需要借助其子类实例化对象
        List list = new ArrayList();

        list.add("a");
        list.add("a");//可重复
        list.add(1,"abc");//可在指定位置添加元素
        System.out.println(list.get(2));//获取指定位置的元素
        list.remove(2);//删除指定位置的元素
        list.set(1,"c");//将指定位置的元素替换成别的值

        //遍历
        //1.迭代器
        System.out.println("迭代器遍历:");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //2.因为有下标,所以可以通过下标遍历
        System.out.println("通过for循环使用下标遍历:");
        for (int i = 0; i <list.size() ; i++) {
            System.out.println(list.get(i));
        }
        //3.foreach
        System.out.println("for增强遍历:");
        for (Object o : list) {
            System.out.println(o);
        }
    }
}

2.ArrayList

ArrayList的底层是Object数组,是线程不安全的。

数组的特点:

  • 优点:检索效率高。因为数组的内存空间是连续的,每个元素所占的空间大小也相同,知道首地址,就可以通过数学表达式计算出下标,通过下标获取元素。
  • 缺点:随机增删元素效率低,因为涉及到元素的位移。(但是从末尾添加元素的效率是不低的);并且不能存储大容量数据,因为可能很难找到一个那么大的连续的内存空间。

查看ArrayList的源码,可以看到,有一个成员变量:

 private static final int DEFAULT_CAPACITY = 10;

ArrayList的默认初始化容量为10(一开始是空数组,容量为0,当添加第一个元素时,就会初始化为10)。也可以通过构造方法自己确定初始化容量。

当元素满了之后,会自动扩容增长到1.5倍的容量。(是增长到)10->15->22.5->......

但是数组扩容的效率比较低,所以尽量避免扩容,最好在一开始就能预估出一个合适的容量。

方法和上述List使用相同。

List的构造方法可以将Set集合转变成List集合。

ArrayList集合是使用最多的,因为它的检索能力高,插入也一般都不会随机插入,一般都是在元素末尾插入,效率也不低。所以在实际开发中,ArrayList的使用是比较多的。

3.LinkedList

LinkedList的底层是双向链表。

链表的基本单元是节点Node,双向链表节点有三部分:存储的数据(Object element)、上一个元素数据的内存地址(Node pre)、下一个元素数据的内存地址(Node next)。

双向链表示意图:

双向链表的特点:

  • 优点:随机增删元素效率高,因为不需要涉及大量元素的位移。

  • 缺点:随机检索效率低,因为双向链表的内存地址不连续,每次都需要从双向链表的头节点开始遍历检索。

LinkedList有一些特殊的方法:以下列举的只是部分。

  • void addFirst():将元素插入开头;
  • void addLast():将元素插入结尾;
  • E getFirst():获得第一个元素;
  • E getLast():获得最后一个元素;
  • E removeFirst():移除第一个元素;
  • E removeLast():移除最后一个元素;
  • E peekFirst():检索但不删除第一个元素;
  • E peekLast():检索但不删除最后一个元素;
  • E pollFirst():检索并删除第一个元素;
  • E peekLast():检索并删除最后一个元素;
  • E pop():从列表中弹出一个元素;
  • void push(E e):将e放入此列表中。

方法的使用很简单,故在此不做过多赘述。

4.Vector

Vector的底层也是数组,但是Vector的线程安全的。但是效率比较低,现在使用比较少。

Vector的初始容量为10,扩容会增长到两倍。10->20->40->......


Collections工具类可以将线程不安全的集合转变成线程安全的集合。

Collections.synchronizedList(new ArrayList());

水平有限,若有错误望指出~

posted @ 2021-02-09 15:25  deng-hui  阅读(123)  评论(0编辑  收藏  举报