java集合汇总(二) List

List

interface Listextends Collection   

有序集合  可以精准控制列表中每个元素的位置

方法

继承方法请看  Collection

E get(int index)     返回此列表中指定位置的元素

E set(int index,E element)   用指定的元素替换此列表中指定位置的元素。

E remove(int index)   从列表中删除指定元素的第一个出现(如果存在)

int indexOf(Object o)     回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。

int lastIndexOf(Object o)    返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。

ListIterator listIterator()   返回列表中的列表迭代器(按适当的顺序)。

ListIterator listIterator(int index)      从列表中的指定位置开始,返回列表中的元素(按正确顺序)的列表迭代器。

List subList(int fromIndex,int toIndex)     返回此列表中指定的fromIndex(含)和toIndex之间的视图

ListIterator

interface ListIterator<E> extends Iterator<E>  

允许程序员沿任一方向遍历列表的列表的迭代器      List中Iterator的实现类

add(E e)    将指定的元素插入列表(可选操作)。 
hasNext()    返回 true  如果遍历正向列表,列表迭代器有多个元素。
hasPrevious()   返回 true   如果遍历反向列表,列表迭代器有多个元素。
E next()    返回列表中的下一个元素,并且前进光标位置。  
int nextIndex()    返回随后调用 next()返回的元素的索引.
int previousIndex()   返回由后续调用 previous()返回的元素的索引。  
void remove()    从列表中删除由 next()或 previous()返回的最后一个元素(可选操作)。  
void set(E e)    用 指定的元素替换由 next()或 previous()返回的最后一个元素(可选操作)。 

ArrayList

class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

 底层使用数组实现的存储类       特点:查询效率高 增删效率低 线程不安全  可以有null值

ArrayList()   构造方法里面初始化一个数组 用来储存数据

 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

 public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

 boolean add(E e)  如果数组长度足够则添加改元素到数组 不够就增加现有长度的一半 然后把原有的元素添加到新数组中

 public boolean add(E e) {
        ensureCapacityInternal(size + 1);   // 判断数组集合的长度是否够
        elementData[size++] = e;  //
        return true;
    }

 private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {  // 数组为空
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); //默认10个长度
        }
        ensureExplicitCapacity(minCapacity); 
    }

    // 如果该数组是刚初始化的  minCapacity =10   如果不是 mincapacity = size+1
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
    // 如果数组长度不够放该长度 调用grow
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

 private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1); //增加原始数组的一半
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //把旧数组的元素拷贝到新长度的数组 然后返回
        elementData = Arrays.copyOf(elementData, newCapacity); 
    }

 E remove(int index) 把要删除的元素位置前边和后边 拷贝到一个新数组里面 然后把最后一个位置的元素 =null

public E remove(int index) {
        modCount++;
        E oldValue = (E) elementData[index];
        int numMoved = size - index - 1;
       // 把要删除的位置前面和后面拷贝到一个新数组  
        if (numMoved > 0)
            //要拷贝的数组 要拷贝的开始位置   拷贝到的数组  要拷贝的位置   拷贝的个数
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; 
        return oldValue;
    }

ListIterator<E> listIterator()   获取该集合的迭代器      

public ListIterator<E> listIterator() {
        return new ListItr(0);
    }


private class ListItr extends Itr implements ListIterator<E> {
     
.... 
    }

 Itr 

class ListItr extends Itr implements ListIterator<E>
Array 的列表迭代器

  cursor   lastRet  

int cursor;       // 下一次要返回的位置
int lastRet = -1; // 当前返回位置

boolean hasNext() 如果游标小于数组数 返回ture 

 protected int limit = ArrayList.this.size;
 public boolean hasNext() {
            return cursor < limit;
 }

 E next() 返回当前游标的元素  然后游标+1  lastRet=当前返回元素的位置

public E next() {
            int i = cursor;   // i 等于当前游标
            Object[] elementData = ArrayList.this.elementData;
            cursor = i + 1;  // 游标 +1 
            return (E) elementData[lastRet = i];  //lastRet = 返回位置   返回当前元素
        }

void remove() 数组删除该游标的元素 游标(cursor)=上一次输出的位置  上一次位置(lastRet)等于-1 size()-- 

public void remove() {
            try {
                ArrayList.this.remove(lastRet); // 删除已经输出的位置的元素
                cursor = lastRet; // 下一个输出位置 等于 前一个位置
                lastRet = -1; // 已经输出的元素  删除  所以已经输出的没了 所以lastRet为-1
                expectedModCount = modCount;
                limit--; 
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

ListItr

ListItr extends Itr implements ListIterator<E> 

构造方法    cursor 下一输出的位置  表示从什么位置开始

ListItr(int index) {
            super();
            cursor = index;
        }

boolean hasPrevious()   int nextIndex()    int previousIndex()

 public boolean hasPrevious() {      // 是否有上一个元素
            return cursor != 0;
        }

        public int nextIndex() {     //下一个输出元素的位置
            return cursor;
        }

        public int previousIndex() { //上一个输出元素的位置
            return cursor - 1;
        }

E previous()   输出上一个输出的元素  

public E previous() {  
            int i = cursor - 1;  // 游标-1
            Object[] elementData = ArrayList.this.elementData;
            cursor = i;  // 
            return (E) elementData[lastRet = i];
        }

LinkedList

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

底层是用双向链表实现的储存  查询效率低  增删效率高  线程不安全  可以为null值

static class Node<E>   链表保存数据类  

 private static class Node<E> {
        E item;  // 数据
        Node<E> next; // 下一个节点
        Node<E> prev; //上一个节点
    }

  first  last   //

    // 链表第一个
    transient Node<E> first;
    
    // 链表最后一个
    transient Node<E> last;

boolean add(E e) 把E放到Node对象中 假如last==null 说明链表没有数据 frist==新的Node   假如last!=null 最后一个Node链接新的 last=新Node  

public boolean add(E e) {
        linkLast(e);
        return true;
    }

void linkLast(E e) {
        final Node<E> l = last;
        // 新建一个Node  把链表最后一个node放到新的前面
        final Node<E> newNode = new Node<>(l, e, null);
        // last 等于 新建的node 
        last = newNode;
        if (l == null)  // 链表没有数据 把新Node当成第一个
            first = newNode;
        else
            l.next = newNode; // last 等于 新的node
        size++;
        modCount++;
    }

E remove(int index)   

 public E remove(int index) {
        checkElementIndex(index); //检测index 是否规范
        return unlink(node(index));
    }

 E unlink(Node<E> x) {   
        final E element = x.item; // 取出要删除位置的数据
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;
        if (prev == null) { // 该Node前面节点为空说明是 frist Node  
            first = next; //  让该节点下一个节点 = frist (间接删除)
        } else {  // 该Node 前一个节点的next  = 该Node的后一个节点
            prev.next = next;
            x.prev = null;
        }
     
        if (next == null) {  // 该Node后面的节点为空说明是last节点  
            last = prev;// 让该节点的上一个节点 = last(间接删除)
        } else { //该Node 后一个节点的prev  = 该Node的前一个节点
            next.prev = prev;
            x.next = null;
        }
        x.item = null;
        size--;
        modCount++;
        return element;
    }

Node<E> node(int index) 判断index 是否大于size/2  大于从链表后面开始遍历 小于从前面开始 最后返回该位置的node 

Node<E> node(int 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;
        }
    }

E get(int index)    返回该位置节点的数据

 public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
E set(int index, E element)  设置Index位置上的值 返回修改掉的值
public E set(int index, E element) {
        Node<E> x = node(index);
        E oldVal = x.item;
        x.item = element;
        return oldVal;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值