zoukankan      html  css  js  c++  java
  • JAVA_list总结

    list,列表序列。是编程工作充常用的对象,类似数组,用于存储统一类型的集合的对象。
    先放结论:

    类型 数据结构 特点描述
    ArrayList 数组 最常用,随机访问高效,插入删除效率低
    LinkedList 双向链表 随机访问效率低,但随机插入、随机删除效率低
    Vector 数组 类似ArrayList,但线程安全
    Stack 它继承于Vector,先进后出

    ArrayList

    首先,ArrayList的本质是数组,在jdk1.8.0_121的java.util.ArrayList中,可以看到以下代码

    transient Object[] elementData; // non-private to simplify nested class access
    

    这就是ArrayList的本质,一个Object[],只不过,在add的时候,会自动的进行扩容而已。

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    

    也因此:

    1. 随机访问效率高(直接elementData[i]就可以取得对象)
    2. 插入删除慢(每次插入删除,尤其是对非尾对象进行改变时,都会导致Object[] elementData结构整个的变动)
    3. 线程不安全(单纯的数组,没有做任何保护处理)

    推荐使用方法:

    // ArrayList基本例子
    List<String> arrayList = new ArrayList<String>();
    arrayList.add("test1");
    arrayList.add("test2");
    arrayList.add("test3");
    for (int i = 0; i < arrayList.size();i++){
        System.out.println(arrayList.get(i));
    }
    

    LinkedList

    源码(jdk1.8.0_121):

    transient Node<E> first;
    
    transient Node<E> last;
    
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;
    
        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
    

    是的,这就是双向链表,只保存首尾两个节点,同时,每个节点保存其自身前后节点地址。也因此:

    1. 访问效率低(非首尾节点时,只能从首尾节点开始,一个一个去寻找)
    2. 插入删除效率高(只需要创建或者删除节点,并且调整相邻节点的地址即可)
    3. 线程不安全(节点,没有做任何保护处理)

    推荐使用方法:

    // linkedList基本例子
    List<String> linkedList = new LinkedList<String>();
    linkedList.add("test1");
    linkedList.add("test2");
    linkedList.add("test3");
    for (String data : linkedList){
        System.out.println(data);
    }
    

    另外,用于LinkedList的implements包含Deque,而Deque继承Queue,所以LinkedList也可作为队列来使用。
    例子:

    Queue<String> queue = new LinkedList<String>();
    queue.add("test1");
    queue.add("test2");
    queue.add("test3");
    System.out.println(queue.size());
    for (int i = 0; i < 3;i++){
        System.out.println(queue.poll());
    }
    System.out.println(queue.size());
    // 结果:
    // 3
    // test1
    // test2
    // test3
    // 0
    

    Vector

    源码(jdk1.8.0_121):

    protected Object[] elementData;
    

    是的,和ArrayList一样,Vector的本质是一个数组,区别在于相关的方法:

    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
    

    对,重点就是synchronized,因为Vector的方法都有synchronized,有了线程的保护,所以Vector是线程安全的。
    Vector类似ArrayList,是线程安全的。知道这一点就足够了。

    ** !但是! **
    虽然Vector是线程安全的,但是想要使用线程安全的ArrayList的时候,简易使用JUC集合类中的CopyOnWriteArrayList。


    Stack

    源码(jdk1.8.0_121):

    protected Object[] elementData;
    

    又来?是的,Stack的底层仍然是一个数组,但是相关的方法却大不一样。虽然由于继承父类Vector,add这种方法还是存在,但是却一般不用。一般使用的是以下方法:

    public E push(E item) {
        addElement(item);
    
        return item;
    }
    public synchronized E pop() {
        E       obj;
        int     len = size();
    
        obj = peek();
        removeElementAt(len - 1);
    
        return obj;
    }
    public synchronized E peek() {
        int     len = size();
    
        if (len == 0)
            throw new EmptyStackException();
        return elementAt(len - 1);
    }
    

    说明:
    push:将元素推入栈中,通过将元素追加的数组的末尾中。
    peek:取出栈顶元素,不执行删除,返回数组末尾的元素。
    pop:取出栈顶元素,将该元素从栈中删除,返回。
    总之:

    1. 使用push插入,用peek或pop去除(符合堆栈特性)
    2. 线程安全(使用synchronized)

    例子:

    // stack基本例子
    Stack<String> stack = new Stack<String>();
    stack.push("test1");
    stack.push("test2");
    stack.push("test3");
    for (int i = 0; i < 3;i++){
        System.out.println(stack.pop());
    }
  • 相关阅读:
    用户控件
    垃圾弟弟
    如何解决“呈现控件时出错”的问题
    IE与FireFox差距
    NavigateUrl属性绑定
    table
    firefox不支持attachEvent,attach
    转 jQuery分类 
    GridView列数字、货币和日期的显示格式
    appendChild
  • 原文地址:https://www.cnblogs.com/changfanchangle/p/8867445.html
Copyright © 2011-2022 走看看