学习list

 

一.集合的基本结构图

collection 的方法

 

add(E element)确保此 collection 包含指定的元素。 
addAll(Collection<? extends E> c)将指定 collection 中的所有元素都添加到此 collection 中。
clear()从collection中移除所有元素。
contains(Object o)如果collection包含指定的元素,则返回 true。
containsAll(Collection<?> c)如果collection包含指定 collection 的所有元素,则返回 true。
equals(Object o) 比较指定的对象与此 collection 是否相等。
hashCode() 返回此collection的哈希码值。
isEmpty() 如果此 collection 不包含元素,则返回 true。
remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话。
removeAll(Collection<?> c)移除此 collection 中那些也包含在指定 collection 中的所有元素。
retainAll(Collection<?> c)仅保留此 collection 中那些也包含在指定 collection 的元素。
size()返回此 collection 中的元素数。
toArray()返回包含此 collection 中所有元素的数组。
toArray(T[] a) 返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。
iterator()返回在此 collection 的元素上进行迭代的迭代器。(继承的方法)

 

 

 

 

二.list中提供的方法

 

继承collection的所有方法把其中的collection改成列表,大致意思和用法不变。变的方法在下面重写。
add(E element)向列表的尾部添加指定的元素。 
add(int index,E element)在列表的指定位置插入指定元素。将当前处于该位置的元素(如果有的话)和所有后续元素向右移动(在其索引中加 1)。
addAll(int index,Collection<? extends E> c)将指定 collection 中的所有元素都插入到列表中的指定位置。                                  
get(int index) 返回列表中指定位置的元素。
indexOf(Object o)  返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。 
lastIndexOf(Object o) 返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。
remove(int index) 移除列表中指定位置的元素。
remove(Object o)从此列表中移除第一次出现的指定元素(如果存在)。
set(int index, E element)用指定元素替换列表中指定位置的元素。
subList(int fromIndex, int toIndex)返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。 
toArray()  返回按适当顺序包含列表中的所有元素的数组(从第一个元素到最后一个元素)。 
toArray(T[] a) 同collection, 且按适当顺序排列。
iterator() 返回按适当顺序在列表的元素上进行迭代的迭代器。 
listIterator() 返回此列表元素的列表迭代器(按适当顺序)。 
listIterator(int index) 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。 

 

 

 

 

 

 

 

 

 

 

 

 

 

三.下面说一说Aarraylist和linkedlist

  1.AarrayList:

    对于ArrayList而言,它实现List接口、底层使用数组保存所有元素。其操作基本上是对数组的操作。下面我们来分析ArrayList的源代码:

  1)底层使用数组实现

  

private transient Object[] elementData; 

   2)构造方法:

ArrayList提供了三种方式的构造器,可以构造一个默认初始容量为10的空列表、构造一个指定初始容量的空列表以及构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回它们的顺序排列的。

public ArrayList() {  
    this(10);  
}  
  
public ArrayList(int initialCapacity) {  
    super();  
    if (initialCapacity < 0)  
        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);  
    this.elementData = new Object[initialCapacity];  
}  
  
public ArrayList(Collection<? extends E> c) {  
    elementData = c.toArray();  
    size = elementData.length;  
    // c.toArray might (incorrectly) not return Object[] (see 6260652)  
    if (elementData.getClass() != Object[].class)  
        elementData = Arrays.copyOf(elementData, size, Object[].class);  

3)存储

ArrayList提供了set(int index, E element)、add(E e)、add(int index, E element)、addAll(Collection<? extends E> c)、addAll(int index, Collection<? extends E> c)这些添加元素的方法。下面我们一一讲解:

// 用指定的元素替代此列表中指定位置上的元素,并返回以前位于该位置上的元素。  
public E set(int index, E element) {  
    RangeCheck(index);  
  
    E oldValue = (E) elementData[index];  
    elementData[index] = element;  
    return oldValue;  
}  
// 将指定的元素添加到此列表的尾部。  
public boolean add(E e) {  
    ensureCapacity(size + 1);   
    elementData[size++] = e;  
    return true;  
}  
// 将指定的元素插入此列表中的指定位置。  
// 如果当前位置有元素,则向右移动当前位于该位置的元素以及所有后续元素(将其索引加1)。  
public void add(int index, E element) {  
    if (index > size || index < 0)  
        throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);  
    // 如果数组长度不足,将进行扩容。  
    ensureCapacity(size+1);  // Increments modCount!!  
    // 将 elementData中从Index位置开始、长度为size-index的元素,  
    // 拷贝到从下标为index+1位置开始的新的elementData数组中。  
    // 即将当前位于该位置的元素以及所有后续元素右移一个位置。  
    System.arraycopy(elementData, index, elementData, index + 1, size - index);  
    elementData[index] = element;  
    size++;  
}  
// 按照指定collection的迭代器所返回的元素顺序,将该collection中的所有元素添加到此列表的尾部。  
public boolean addAll(Collection<? extends E> c) {  
    Object[] a = c.toArray();  
    int numNew = a.length;  
    ensureCapacity(size + numNew);  // Increments modCount  
    System.arraycopy(a, 0, elementData, size, numNew);  
    size += numNew;  
    return numNew != 0;  
}  
// 从指定的位置开始,将指定collection中的所有元素插入到此列表中。  
public boolean addAll(int index, Collection<? extends E> c) {  
    if (index > size || index < 0)  
        throw new IndexOutOfBoundsException(  
            "Index: " + index + ", Size: " + size);  
  
    Object[] a = c.toArray();  
    int numNew = a.length;  
    ensureCapacity(size + numNew);  // Increments modCount  
  
    int numMoved = size - index;  
    if (numMoved > 0)  
        System.arraycopy(elementData, index, elementData, index + numNew, numMoved);  
  
    System.arraycopy(a, 0, elementData, index, numNew);  
    size += numNew;  
    return numNew != 0;  
} 

https://blog.csdn.net/u010305706/article/details/51007826

 

下面是linkedlist的源码解析

package java.util;

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    transient int size = 0;

    // 第一个结点
    transient Node<E> first;

    // 最后一个结点
    transient Node<E> last;

    // 构造一个空列表
    public LinkedList() {
    }

    // 构造一个包含指定 Collection 中的元素的列表,
    // 这些元素按其 Collection 的迭代器返回的顺序排列
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

    // 返回此列表的第一个元素
    public E getFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }

    // 返回此列表的最后一个元素
    public E getLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
    }

    // 移除并返回此列表的第一个元素
    public E removeFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
    }

    // 移除并返回此列表的最后一个元素
    public E removeLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);
    }

    // 将指定元素插入此列表的开头
    public void addFirst(E e) {
        linkFirst(e);
    }

    // 将指定元素添加到此列表的结尾
    public void addLast(E e) {
        linkLast(e);
    }

    // 判断此列表包含指定元素,如果是,则返回true
    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }

    // 返回此列表的元素个数
    public int size() {
        return size;
    }

    // 将指定元素添加到此列表的结尾
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

    // 从此列表中移除首次出现的指定元素(如果存在返回true,否则返回false)
    public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

    // 添加指定 collection 中的所有元素到此列表的结尾,
    // 顺序是指定 collection 的迭代器返回这些元素的顺序
    public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }

    // 将指定 collection 中的所有元素从指定位置开始插入此列表
    public boolean addAll(int index, Collection<? extends E> c) {
        checkPositionIndex(index);// 检查index的范围

        Object[] a = c.toArray();
        int numNew = a.length;
        if (numNew == 0)          // 如果c为空,则返回false
            return false;

        Node<E> pred, succ;
        if (index == size) {      // 插入位置为列表末尾
            succ = null;
            pred = last;
        } else {
            succ = node(index);   // 插入位置不是列表末尾
            pred = succ.prev;
        }
        // 将元素添加到pred末尾
        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;
        }
        // 将剩余元素整合一起
        if (succ == null) {
            last = pred;
        } else {
            pred.next = succ;
            succ.prev = pred;
        }

        size += numNew;
        modCount++;
        return true;
    }

    // 从此列表中移除所有元素
    public void clear() {
        // Clearing all of the links between nodes is "unnecessary", but:
        // - helps a generational GC if the discarded nodes inhabit
        //   more than one generation
        // - is sure to free memory even if there is a reachable Iterator
        for (Node<E> x = first; x != null; ) {
            Node<E> next = x.next;
            x.item = null;
            x.next = null;
            x.prev = null;
            x = next;
        }
        first = last = null;
        size = 0;
        modCount++;
    }

    /********************** 位置访问操作 **************************/

    // 返回此列表中指定位置处的元素
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }

    // 将此列表中指定位置的元素替换为指定的元素
    public E set(int index, E element) {
        checkElementIndex(index);
        Node<E> x = node(index);
        E oldVal = x.item;
        x.item = element;
        return oldVal;
    }

    // 在此列表中指定的位置插入指定的元素
    public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)     // 插入到末尾
            linkLast(element);
        else
            linkBefore(element, node(index));
    }

    // 移除此列表中指定位置处的元素
    public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
    }

    // (包访问权限)返回指定位置上的结点(非空)
    Node<E> node(int index) {
        // assert isElementIndex(index);
        // 根据指定位置是在左半边还是在右半边,
        // 来决定是用正向寻找还是反向寻找
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

    /********************** Search操作 **************************/

    // 返回此列表中首次出现的指定元素的索引,
    // 如果此列表中不包含该元素,则返回 -1
    public int indexOf(Object o) {
        int index = 0;
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
    }

    // 返回此列表中最后出现的指定元素的索引,
    // 如果此列表中不包含该元素,则返回 -1
    public int lastIndexOf(Object o) {
        int index = size;
        if (o == null) {
            for (Node<E> x = last; x != null; x = x.prev) {
                index--;
                if (x.item == null)
                    return index;
            }
        } else {
            for (Node<E> x = last; x != null; x = x.prev) {
                index--;
                if (o.equals(x.item))
                    return index;
            }
        }
        return -1;
    }

    /********************** Queue操作 **************************/

    // 获取但不移除此列表的头(第一个元素)
    public E peek() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
    }

    // 获取但不移除此列表的头(第一个元素)
    public E element() {
        return getFirst();
    }

    // 获取并移除此列表的头(第一个元素)
    public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }

    // 获取并移除此列表的头(第一个元素)
    public E remove() {
        return removeFirst();
    }

    // 将指定元素添加到此列表的末尾(最后一个元素)
    public boolean offer(E e) {
        return add(e);
    }

    /********************** Deque操作 **************************/

    // 在此列表的开头插入指定的元素
    public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }

    // 在此列表末尾插入指定的元素
    public boolean offerLast(E e) {
        addLast(e);
        return true;
    }

    // 获取但不移除此列表的第一个元素
    public E peekFirst() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
     }

    // 获取但不移除此列表的最后一个元素
    public E peekLast() {
        final Node<E> l = last;
        return (l == null) ? null : l.item;
    }

    // 获取并移除此列表的第一个元素
    public E pollFirst() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }

    // 获取并移除此列表的最后一个元素
    public E pollLast() {
        final Node<E> l = last;
        return (l == null) ? null : unlinkLast(l);
    }

    // 将元素推入此列表所表示的堆栈(插入到列表的头)
    public void push(E e) {
        addFirst(e);
    }

    // 从此列表所表示的堆栈处弹出一个元素(获取并移除列表第一个元素)
    public E pop() {
        return removeFirst();
    }

    // 从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表)
    public boolean removeFirstOccurrence(Object o) {
        return remove(o);
    }

    // 从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表)
    public boolean removeLastOccurrence(Object o) {
        if (o == null) {
            for (Node<E> x = last; x != null; x = x.prev) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = last; x != null; x = x.prev) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

    // 返回此列表中的元素的列表迭代器(按适当顺序),从列表中指定位置开始
    public ListIterator<E> listIterator(int index) {
        checkPositionIndex(index);
        return new ListItr(index);
    }

    // (私有类)结点结构
    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;
        }
    }

    /**
     * @since 1.6
     */
    public Iterator<E> descendingIterator() {
        return new DescendingIterator();
    }

    /**
     * Adapter to provide descending iterators via ListItr.previous
     */
    private class DescendingIterator implements Iterator<E> {
        private final ListItr itr = new ListItr(size());
        public boolean hasNext() {
            return itr.hasPrevious();
        }
        public E next() {
            return itr.previous();
        }
        public void remove() {
            itr.remove();
        }
    }

    @SuppressWarnings("unchecked")
    private LinkedList<E> superClone() {
        try {
            return (LinkedList<E>) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }

    // 返回此 LinkedList 的浅表副本
    public Object clone() {
        LinkedList<E> clone = superClone();

        // Put clone into "virgin" state
        clone.first = clone.last = null;
        clone.size = 0;
        clone.modCount = 0;

        // Initialize clone with our elements
        for (Node<E> x = first; x != null; x = x.next)
            clone.add(x.item);

        return clone;
    }

    // 返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组
    public Object[] toArray() {
        Object[] result = new Object[size];
        int i = 0;
        for (Node<E> x = first; x != null; x = x.next)
            result[i++] = x.item;
        return result;
    }

    // 返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组;
    // 返回数组的运行时类型为指定数组的类型。
    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        if (a.length < size)
            a = (T[])java.lang.reflect.Array.newInstance(
                                a.getClass().getComponentType(), size);
        int i = 0;
        Object[] result = a;
        for (Node<E> x = first; x != null; x = x.next)
            result[i++] = x.item;

        if (a.length > size)
            a[size] = null;

        return a;
    }

    // 版本序列号
    private static final long serialVersionUID = 876323262645176354L;

    // java.io.Serializable的写入函数
    // 将LinkedList的“容量,所有的元素值”都写入到输出流中
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        // Write out any hidden serialization magic
        s.defaultWriteObject();

        // Write out size
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (Node<E> x = first; x != null; x = x.next)
            s.writeObject(x.item);
    }

    // java.io.Serializable的读取函数:根据写入方式反向读出
    // 先将LinkedList的“容量”读出,然后将“所有的元素值”读出
    @SuppressWarnings("unchecked")
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        // Read in any hidden serialization magic
        s.defaultReadObject();

        // Read in size
        int size = s.readInt();

        // Read in all elements in the proper order.
        for (int i = 0; i < size; i++)
            linkLast((E)s.readObject());
    }
}

总结:从源码中可以看出List是通过一个很关键的实体类Entry来实现链表式的存储的。

  1、Entry、该类是一个实体类、用来表示链表中的一个节点、他包括连接上一个节点的引用、连接下一个节点的引用、和节点的属性。

        2、LinkedList实现了List中要求的使用索引操作的一些方法、LinkedList中是通过private Entry<E> entry(int index)方法将LinkedList中的元素与索引关联起来的、他对于传进来的每个index都会与size进行比较、若index >= size/2 那么就从后开始向前依次遍历LinkedList中元素、直到LinkedList中第index个元素被查找到、若inde<size/2、则从LinkedList开头依次遍历所有元素直到第index个元素被查找到并返回、这也是通过随机访问LinkedList效率非常低的原因。

        3、由LinkedList的数据结构的特性、决定其方法很多、但是也是有规律可循、其中一部分的方法对相同结果有两种处理、一种是返回null、一种是抛出异常、这些方法如下

返回值:   异常           null        异常              null  
                          
     addFirst(e)    offerFirst(e)    addLast(e)       offerLast(e)  
  
     removeFirst()  pollFirst()      removeLast()     pollLast()  
  
     getFirst()     peekFirst()      getLast()        peekLast()  

 4、当LinkedList作为先进先出(FIFO)队列时、下列方法等效

队列方法       等效方法  
add(e)        addLast(e)  
offer(e)      offerLast(e)  
remove()      removeFirst()  
poll()        pollFirst()  
element()     getFirst()  
peek()        peekFirst()  

5、当LinkedList作为先进后出(FILO)栈时、下列方法等效

栈方法        等效方法  
push(e)      addFirst(e)  
pop()        removeFirst()  
peek()       peekFirst()  

 

 

 

下面说说ArrayList,LinkedList和的区别  

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 

 

转载于:https://www.cnblogs.com/strugglecola/p/8889216.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值