1. 程式人生 > >Android面試篇之ArrayList和LinkedList的區別

Android面試篇之ArrayList和LinkedList的區別

● 資料結構

ArrayList基於動態陣列;LinkedList基於連結串列

● 隨機訪問

ArrayList優於LinkedList,因為LinkedList要移動指標來查詢,下面以get方法為例

        //ArrayList的get方法,直接從陣列中獲取元素值
        public E get(int index) {
            if (index < 0 || index >= this.size)
              throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
            if (ArrayList.this.modCount != this.modCount)
                throw new ConcurrentModificationException();
            return (E) ArrayList.this.elementData[offset + index];
        }
        
        
        //LinkedList的get方法,node方法用來進行查詢
        public E get(int index) {
             checkElementIndex(index);
             return node(index).item;
        }
                
        Node<E> node(int index) {
            if (index < (size >> 1)) {//若index小於size的一半,則從頭開始查詢
                Node<E> x = first;
                for (int i = 0; i < index; i++)
                    x = x.next;
                return x;
            } else {//若index大於size的一半,則從末尾向前開始查詢
                Node<E> x = last;
                for (int i = size - 1; i > index; i--)
                    x = x.prev;
                return x;
            }
        }

● 插入刪除

1. 末尾插入,兩個的時間複雜度都是O(1),所以差不多 [刪除操作也同理]

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

            void linkLast(E e) {
                final Node<E> l = last;
                final Node<E> newNode = new Node<>(l, e, null);
                last = newNode;
                if (l == null)
                    first = newNode;
                else
                    l.next = newNode;
                size++;
                modCount++;
            } 

2. 中間插入,時間複雜度也都是O(n),所以也差不多 [刪除操作也同理]

            //ArrayList的add方法
            public void add(int index, E element) {
                if (index > size || index < 0)
                    throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

                ensureCapacityInternal(size + 1);  // Increments modCount!!
                System.arraycopy(elementData, index, elementData, index + 1,
                                 size - index);//index後面的元素後移,時間複雜度O(n)
                elementData[index] = element;
                size++;
            }

            //LinkedList的add方法
            public void add(int index, E element) {
                checkPositionIndex(index);

                if (index == size) //index等於size時,直接連結到末尾
                    linkLast(element);
                else //否則直接將element連結到node(index)前面,node(index)的時間複雜度也是O(n)
                    linkBefore(element, node(index));
            }

            void linkLast(E e) {
                final Node<E> l = last;
                final Node<E> newNode = new Node<>(l, e, null);
                last = newNode;
                if (l == null)
                    first = newNode;
                else
                    l.next = newNode;
                size++;
                modCount++;
            }

            void linkBefore(E e, Node<E> succ) {
                // assert succ != null;
                final Node<E> pred = succ.prev;
                final Node<E> newNode = new Node<>(pred, e, succ);
                succ.prev = newNode;
                if (pred == null)
                    first = newNode;
                else
                    pred.next = newNode;
                size++;
                modCount++;
            }