List面试准备

你了解过那些List集合?

ArrayList、LinkedList 、Vector

讲讲ArrayList吧

ArrayList 底层是一个数组。
构造器三种:
①无参构造,初始化一个默认大小为10的数组。
②给一个capacity初始化为这个大小。
③给定另一个已有的集合A,调用A的toArray方法,A如果为0那么也按无参构造处理,
如果A中有元素那么就调用Array.copyOf函数复制过来。

add的话就是跟普通数组一样,多了扩容的判断与操作。
真正add前先判断扩容

		//1.5倍扩容   jdk 1.8
        int newCapacity = oldCapacity + (oldCapacity >> 1);

如果是用索引add 那么会调用native的移动数组方法

    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

特点就是随机访问快,在中间插入效率低下。


LinkedList也说说吧,底层是怎么实现的

LinkedList是一个双向链表,
初始化两种方式:
①空构造
②使用一个存在的集合。调用addAll方法先toArray成Object数组 然后进行尾插法,插入前经过强转LinkedList给的泛型。

采用尾插法

for (Object o : a) {
    
    
            @SuppressWarnings("unchecked") E e = (E) o;
            Node<E> newNode = new Node<>(pred, e, null);
            if (pred == null)
                first = newNode;
            else
                pred.next = newNode;
            pred = newNode;
        }

在头部和尾部get元素的和删除的如果不存在都抛异常。

如果是get一个index,会先进入一个判断方法判断,不在范围也是抛异常

public E getFirst() {
    
    
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }

    /**
     * Returns the last element in this list.
     *
     * @return the last element in this list
     * @throws NoSuchElementException if this list is empty
     */
    public E getLast() {
    
    
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
    }

    /**
     * Removes and returns the first element from this list.
     *
     * @return the first element from this list
     * @throws NoSuchElementException if this list is empty
     */
    public E removeFirst() {
    
    
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
    }

    /**
     * Removes and returns the last element from this list.
     *
     * @return the last element from this list
     * @throws NoSuchElementException if this list is empty
     */
    public E removeLast() {
    
    
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);
    }

四种add方法:
①add一个元素:调用尾插法
②addfirst方法:调用头插法
③addlast方法:调用尾插法
④add index,key:先判断范围,超范围抛异常,再看是不是最后一个位置,如果是那就直接调用尾插法,否则的话就找吧。

offer的话都是调用add方法,尾插 ,最后返回一个true。
push是调用addFirst和pop 调用removeFirst,都是对头进行操作

Vector呢,是线程安全的吗?

是的 几乎所有方法都使用了synchronized关键字

Vector是怎么扩容的?

扩容两倍增长,如果没有指定,数组进行迁移

猜你喜欢

转载自blog.csdn.net/BOWWOB/article/details/113663591