面试_java_LinkedList

129 阅读2分钟

LinkedList就是一个双向链表结构,存储地址是不连续的,底层通过一个个内部类Node的实例串联起来存储数据,没有容量限制,增删节点不需要移动数据,速度快,但是随机访问速度慢,需要从头到尾或者从尾到头遍历,适合增删频繁,随机访问较少的业务场景。非同步,线程不安全;支持null元素、有顺序、元素可以重复;可以作为栈、队列、双端队列数据结构使用。


public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable


存储结构

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;
    }
}



LinkedList查找元素每次都是从头部开始吗?

不是的,LinkedList的查找底层是通过node(int index)方法实现的,这个方法会先判读index是否大于链表的长度的一半,如果大于就从尾部开始遍历,如果不大于,就从头部开始遍历




有什么办法提升链表随机查找速度吗?

可以通过跳表方式增强随机查找能力,即维护一个节点索引数组,数组中保存节点的地址引用,数组下标和节点的某个数据要一致,这样直接通过数组下标找到节点的引用,如果在数组找不到精确匹配的索引,可以找一个就近的索引,得到节点,往后遍历节点即可,这样也能大大提升速度

LinkedList<String> list=new LinkedList<>();



// 增
Boolean offerFirst(E e);   // 【Deque接口】 将对象e插入到双端队列头部
// 同作用:【Deque接口】 void addFirst(E e); 容间不足时,抛出IllegalStateException异常; 不推荐
// 同作用:【Deque接口】 void push(E e);


Boolean offerLast(E e); //  【Deque接口】 将对象e插入到双端队列尾部;
// 同作用:【Deque接口】 void addLast(E e); 容间不足时,抛出IllegalStateException异常; 不推荐


Boolean offer(E e);// 【Queue接口】  将对象e插入队列尾部,成功返回true,失败(没有空间)返回false
// 同作用:【Queue接口】 Boolean add(obj); 若失败(没有空间)抛出异常IllegalStateException;  不推荐



list.add(index, obj);       // void     在指定位置插入指定元素.
list.addAll(tmp_list);      // boolean  插入指定列表到列表尾部.
list.addAll(index,tmp_list);// boolean  在指定位置插入指定列表.



// 删
E pollFirst(); // 【Deque接口】  获取并移除队列第一个元素,队列为空,返回null;
// 同作用:【Deque接口】 E removeFirst();队列为空,抛出NoSuchElementException异常; 不推荐


E pollLast();  // 【Deque接口】 获取并移除队列最后一个元素,队列为空,返回null;
// 同作用:【Deque接口】 E removeLast();队列为空,抛出NoSuchElementException异常; 不推荐
// 同作用:【Deque接口】  E pop();


E poll();   // 【Queue接口】 获取并移除队列头部元素,如果队列为空,返回null;
// 同作用:【Queue接口】 E remove(); 如果队列为空,抛出NoSuchElementException异常;  不推荐

Boolean removeFirstOccurrence(Object o); // 【Deque接口】 移除第一个满足 (o==null ? e==null : o.equals(e)) 的元素
Boolean removeLastOccurrence(Object o);// 【Deque接口】 移除最后一个满足 (o==null ? e==null : o.equals(e)) 的元素


list.remove(obj);           // boolean 删除指定元素
list.remove(index);         // object 根据索引删除元素
list.removeAll(tmp_list);   // boolean  批量删除元素
list.removeIf(e -> 条件);   // boolean   删除满足指定条件的元素  (e表示列表中的每个元素)
list.retainAll(tmp_list);   // boolean  将存在于list但不存在于tmp_list的元素从list中删除
list.clear();               // void 清空列表






// 改
list.set(index, new_obj);               // object   修改指定位置的元素
list.replaceAll(e -> 修改动作 );         // void     修改所有元素
list.sort(Comparator.naturalOrder());   // void     排序。可以用Comparator,也可以用Comparable
list.toString();                        // string   转化为字符串







// 查
E peekFirst();  // 【Deque接口】 获取队列第一个元素,队列为空,返回null;
// 同作用: 【Deque接口】   E getFirst();  队列为空,抛出NoSuchElementException异常; 不推荐

E peekLast();  // 【Deque接口】 获取队列最后一个元素,队列为空,返回null;
// 同作用:  【Deque接口】   E getLast();  队列为空,抛出NoSuchElementException异常; 不推荐

E peek();  // 【Queue接口】 获取但不移除队列头部元素,如果队列为空,返回null;
// 同作用:// 【Queue接口】 E element();  如果队列为空,抛出NoSuchElementException异常;不推荐


Iterator<E> descendingIterator();  // 【Deque接口】 双端队列尾部到头部的一个迭代器;


list.get(index);            // object   返回指定位置的元素
list.indexOf(obj);          // int      返回指定元素的下标
list.lastIndexOf(obj);      // int      返回指定元素最后一次出现的下标
list.contains(obj);         // boolean  查看list中是否存在某个元素
list.containsAll(tmp_list); // boolean  检测list中是否包含指定集合中的所有元素。
list.isEmpty();             // boolean  判空
list.size();                // int      当前列表中元素的个数




www.cnblogs.com/chenpi/p/52…