List接口下集合的特点

List

  • List 是一个接口,它继承于Collection的接口。
  • ArrayList, LinkedList, Vector, Stack是List的4个实现类。
  • 如果涉及到“栈”、“队列”、“链表”等操作,应该考虑用List。
  • 有序集合,可以通过下标访问集合中的元素。
  • 允许重复值,允许有多个null值。

List子类

ArrayList

  1. ArrayList底层实现是数组结构,是一个大小可变的数组,可以通过下标来访问。线程不安全。
    继承AbstractList,实现List接口,提供了相关的添加、删除、修改、遍历等功能。
    实现了RandmoAccess接口,提供了随机访问功能。
    实现了Cloneable接口,可以使用clone方法,能被克隆。
    实现java.io.Serializable接口,则ArrayList支持序列化,能通过序列化去传输。
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  1. 构造与扩容
    通过无参构造,初始化时数组大小为空。
public ArrayList() {
        super();
        this.elementData = EMPTY_ELEMENTDATA;
    }

当添加第一个元素时,调用ensureCapacityInternal方法判断数组是否为空数组,如果为空,将开辟默认大小DEFAULT_CAPACITY = 10;否则调用ensureExplicitCapacity方法,在此方法中,如果空间不够,将进行扩容,调用grow方法,以1.5倍方式进行扩容。

 private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity); //101
    }
 private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        101 - 100
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);  
    } 

3.遍历
三种方式:foreach遍历;循环遍历;迭代器遍历

        //foreach遍历
        for (Object a:list1){
            System.out.print(a+" ");
        }
        //循环遍历
        for (int i=0;i<list1.size();i++){
            System.out.print(list1.get(i)+" ");
        }
        //迭代器遍历
        Iterator<Character> iterator = list1.iterator();
        while (iterator.hasNext()){
            Character next = iterator.next();
            System.out.print(next+" ");
        }
        //ListIterator迭代器遍历 从后往前
        ListIterator iterator1 = list1.listIterator();
        while (iterator1.hasNext()){
            System.out.print(iterator1.next()+" ");
        }
        //从后往前
        ListIterator iterator2 = list1.listIterator(4);
        while (iterator2.hasPrevious()){
            System.out.print(iterator2.previous()+" ");
        }

LinkedList

  1. LinkedList是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。是非同步的,即线程不安全的。
    实现 List 接口,能对它进行队列操作。
    实现 Deque 接口,即能将LinkedList当作双端队列使用。
    实现了Cloneable接口,可以使用clone方法,能被克隆。
    实现java.io.Serializable接口,则LinkedList支持序列化,能通过序列化去传输。
public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  1. 构造与扩容
    LinkedList 是一个双向链表,没有初始化大小,也没有扩容的机制。
    LinkedList 包含一个非常重要的内部类:Node。Node是双向链表节点所对应的数据结构,它包括的属性有:当前节点所包含的值,前驱和后继。
    (2) 从LinkedList的实现方式中可以发现,它不存在LinkedList容量不足的问题。
private static class Node<E> {
        E item;//value
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

Vector

  1. Vector底层是数组。
    继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
    继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。
    实现了RandmoAccess接口,即提供了随机访问功能。
    实现了Cloneable接口,即实现clone()函数,能被克隆。
    和ArrayList不同,Vector中的操作是线程安全的。
public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  1. 构造与扩容
    无参构造函数vector会初始化一个大小为10的空数组。
    随着Vector中元素的增加,Vector的容量也会动态增长,默认情况下Vector2倍扩容。capacityIncrement是与容量增长相关的增长系数。capacityIncrement可看作增长因子。如果增长因子大于0,扩大增长因子个的大小。
    grow方法:如果capacityIncrement不大于0,Vector是2倍扩容;如果大于0,Vector容量扩大capacityIncrement个。

Stack

1.Stack是栈。它的特性是:先进后出。
是继承于Vector的,由于Vector是通过数组实现的,Vector拥有的属性和功能,Stack都拥有。也说明Stack也是通过数组实现的,而非链表。
但是也可以将LinkedList当作栈来使用。

public class Stack<E> extends Vector<E>

2.构造与方法
Stack只有一个默认构造函数。

 /**
     * Creates an empty Stack.
     */
    public Stack() {
    }

执行push时,是通过将元素追加的数组的末尾中。
执行peek时,取出栈顶元素,不执行删除,即返回数组末尾的元素。
执行pop时,取出栈顶元素,并将该元素从栈中删除。

迭代器iterator()

  • 迭代器:集合迭代(集合遍历)的工具。所有常用集合都具备了可迭代功能iterator方法,是最为通用的集合迭代方法。
  • 迭代器模式:提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
  • 迭代器模式就是用迭代器来承担集合遍历的职责。 为遍历不同集合结构提供统一的接口。
  • 只有三个方法:
    boolean hasNext() 判断集合中是否有下一个元素
    E next()获取集合中下一个元素
    void remove();一出元素
//例:
Iterator<Integer> iterator = stack.iterator(); //栈Stack的遍历
        while (iterator.hasNext()) {
            Integer next = iterator.next();
            System.out.print(next + " ");
        }

比较与选择

  1. Vector与ArrayList:
    相同:底层和方法的使用是没有区别。
    初始化时间:ArrayList在添加第一个元素时初始化,Vector是在构造函数时。
    扩容方式:Vector更合理。
    线程安全:vector中所有方法都添加了synchronized锁,所有Vector是线程安全的。ArrayList是线程不安全的。
  2. ArrayList与LinkedList:
    底层结构:ArrayList是数组,LinkedList是双向链表。
    添加删除:ArrayList随机的添加删除时会造成数据的移动,导致效率过低。LinkedList更适合于随机添加删除方法比较频繁的操作,不会有数据的移动。
    随机访问:ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。ArrayList适合随机访问操作比较频繁的。
  3. 线程安全情况下
    多线程条件下需要考虑线程安全问题选择Vector,不需要考虑线程安全则考虑ArrayList。因为加锁操作非常耗时。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值