//5.如果是超过当前数组长度才需要进行数组扩容的操作 /** * 如果新数组大小还是小于传入的容量的话,那就直接取传入的容量作为新数组的长度 * 如果新数组的长度要比最大定义的数组长的话 * (最大的数组长度是Integer.MAX_VALUE-8) * 那么就直接使用Integer.MAX_VALUE作为数组的长度. * 然后就将数组的元素拷贝到一个新的数组中 */ privatevoidgrow(int minCapacity){ int oldCapacity = elementData.length; //右移1位,此处得到新容量是旧容量的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
addAll(Collection<? extends E> c) 方法和普通add方法类似,主要使用了System.arraycopy方法来拷贝指定元素
Set
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//插入到index的下标的位置,然后返回旧的值 public E set(int index, E element){ //判断传入的下标是否越界 rangeCheck(index);
E oldValue = elementData(index); elementData[index] = element; return oldValue; }
privatevoidrangeCheck(int index){ if (index >= size) thrownew IndexOutOfBoundsException(outOfBoundsMsg(index)); }
Get
1 2 3 4 5
public E get(int index){ //判断传入的下标是否越界 rangeCheck(index); return elementData(index); }
Remove
根据传入下标来移除列表中的元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
public E remove(int index){ //判断传入的下标是否越界 rangeCheck(index); //删除操作修改了列表结构 modCount++; E oldValue = elementData(index); //需要进行移动的元素个数 int numMoved = size - index - 1; if (numMoved > 0) //移动数组的元素 System.arraycopy(elementData, index+1, elementData, index, numMoved); //更新列表的元素个数,清除最后一个元素,让GC回收 elementData[--size] = null; // clear to let GC do its work
publicbooleanremove(Object o){ //移除null值元素 if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); returntrue; } } else { //for循环遍历列表,根据对象的equals方法来移除对应元素 for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); returntrue; } } returnfalse; }
//此方法是移除列表中的元素,根据下标志移除 privatevoidfastRemove(int index){ modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
public E next(){ checkForComodification(); int i = cursor; //这里都是判断下标是否越界 if (i >= size) thrownew NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) thrownew ConcurrentModificationException(); //游标+1 cursor = i + 1; return (E) elementData[lastRet = i]; } //在获取元素之前,需要先判断列表结构是否被修改过 finalvoidcheckForComodification(){ if (modCount != expectedModCount) thrownew ConcurrentModificationException(); }
移除元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
publicvoidremove(){ //这个地方就是为什么需要先执行 next 方法后才能调用 remove 方法的原因 if (lastRet < 0) thrownew IllegalStateException(); //在移除元素之前,需要先判断列表结构是否被修改过 checkForComodification();
//添加元素到链表末尾 //将元素包装成Node节点,然后就是链表的操作了 // 如果尾节点是空的,那么将该节点作为头和尾节点 // 如果尾节点非空,那么将该节点作为尾节点,并且加入到链表中 voidlinkLast(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++; } //添加元素到链表头 privatevoidlinkFirst(E e){ final Node<E> f = first; final Node<E> newNode = new Node<>(null, e, f); first = newNode; if (f == null) last = newNode; else f.prev = newNode; size++; modCount++; } //链表操作,将 e 插入到 succ 前面 voidlinkBefore(E e, Node<E> succ){ // succ 不能为null final Node<E> pred = succ.prev; final Node<E> newNode = new Node<>(pred, e, succ); succ.prev = newNode; if (pred == null) //即succ是头节点的情况 first = newNode; else pred.next = newNode; size++; modCount++; } /** * 采用折半法得到index所在的位置(左/右区间) * 然后采用for循环遍历的方式得到index位置上的元素 */ 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; } }
//返回头节点元素内容 public E getFirst(){ final Node<E> f = first; if (f == null) thrownew NoSuchElementException(); return f.item; } //返回尾节点元素内容 public E getLast(){ final Node<E> l = last; if (l == null) thrownew NoSuchElementException(); return l.item; } //获取指定下标的元素 public E get(int index){ checkElementIndex(index); //折半for循环查找指定下标的元素 return node(index).item; } //检查下标是否越界和index是否小于0 privatevoidcheckElementIndex(int index){ if (!isElementIndex(index)) thrownew IndexOutOfBoundsException(outOfBoundsMsg(index)); } privatebooleanisElementIndex(int index){ return index >= 0 && index < size; }
//要求参数 x 不能为null 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) { //该节点是头结点的情况 first = next; } else { prev.next = next; x.prev = null; }
private E unlinkFirst(Node<E> f){ // 要求f是头节点并且不为null final E element = f.item; final Node<E> next = f.next; f.item = null; f.next = null; // help GC first = next; if (next == null) //链表元素只有一个的情况 last = null; else next.prev = null; size--; modCount++; return element; }
private E unlinkLast(Node<E> l){ // 要求l是尾节点并且不为null final E element = l.item; final Node<E> prev = l.prev; l.item = null; l.prev = null; // help GC last = prev; if (prev == null) //链表元素只有一个的情况 first = null; else prev.next = null; size--; modCount++; return element; }
//删除指定元素的节点,利用for循环便利链表,找到第一个配对的元素删除 //注意:如果链表有多个相同的元素,该方法只会删除第一个 publicbooleanremove(Object o){ if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); returntrue; } } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); returntrue; } } } returnfalse; }
Set
1 2 3 4 5 6 7 8 9
public E set(int index, E element){ //检查下标是否越界或者index是否小于0 checkElementIndex(index); //找到index下标的元素,更新该item内容后返回旧值 Node<E> x = node(index); E oldVal = x.item; x.item = element; return oldVal; }
近期评论