腾讯一面!说说ArrayList的遍历foreach与iterator时remove的区别,我一脸懵逼 (2)

在指定的位置处添加指定的元素:

/** * ArrayList: */ public void add(int index, E element) { //index参数校验 rangeCheckForAdd(index); //查看是否需要扩容 ensureCapacityInternal(size + 1); /* 这里数组拷贝的意义,就是将index位置处以及后面的数组元素往后移动一位,以此来挪出一个位置 System.arraycopy是直接对内存进行复制,在大数据量下,比for循环更快 */ System.arraycopy(elementData, index, elementData, index + 1, size - index); //然后将需要插入的元素插入到上面挪出的index位置处就可以了 elementData[index] = element; //最后size+1,代表添加了一个元素 size++; } /** * 第6行代码处: * 检查传入的index索引位是否越界,如果越界就抛异常 */ private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private String outOfBoundsMsg(int index) { return "Index: " + index + ", Size: " + size; } 4 get方法 /** * ArrayList: */ public E get(int index) { //index参数校验 rangeCheck(index); //获取数据 return elementData(index); } /** * 第6行代码处: * 这里只检查了index大于等于size的情况,而index为负数的情况 * 在elementData方法中会直接抛出ArrayIndexOutOfBoundsException */ private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } /** * 第8行代码处: * 可以看到,这里是直接从elementData数组中获取指定index位置的数据 */ @SuppressWarnings("unchecked") E elementData(int index) { return (E) elementData[index]; } 5 remove方法 5.1 remove(Object o)

删除指定的元素:

/** * ArrayList: */ public boolean remove(Object o) { if (o == null) { //如果要删除的元素为null for (int index = 0; index < size; index++) //遍历数组中的每一个元素,找到第一个为null的元素 if (elementData[index] == null) { /* 删除这个元素,并返回true。这里也就是在做清理的工作:遇到一个为null的元素就清除掉 注意这里只会清除一次,并不会全部清除 */ fastRemove(index); return true; } } else { //如果要删除的元素不为null for (int index = 0; index < size; index++) //找到和要删除的元素是一致的数组元素 if (o.equals(elementData[index])) { /* 找到了一个就进行删除,并返回true。注意这里只会找到并删除一个元素, 如果要删除所有的元素就调用removeAll方法即可 */ fastRemove(index); return true; } } /* 如果要删除的元素为null并且找不到为null的元素,或者要删除的元素不为null并且找不到和要删除元素相等的数组元素, 就说明此时不需要删除元素,直接返回false就行了 */ return false; } /** * 第14行和第26行代码处: */ private void fastRemove(int index) { //修改次数+1 modCount++; //numMoved记录的是移动元素的个数 int numMoved = size - index - 1; if (numMoved > 0) /* 这里数组拷贝的意义,就是将index+1位置处以及后面的数组元素往前移动一位, 这会将index位置处的元素被覆盖,也就是做了删除 */ System.arraycopy(elementData, index + 1, elementData, index, numMoved); /* 因为上面是左移了一位,所以最后一个位置相当于腾空了,这里也就是将最后一个位置(--size)置为null 当然如果上面计算出来的numMoved本身就小于等于0,也就是index大于等于size-1的时候(大于不太可能, 是属于异常的情况),意味着不需要进行左移。此时也将最后一个位置置为null就行了。置为null之后, 原有数据的引用就会被断开,GC就可以工作了 */ elementData[--size] = null; } 5.2 remove(int index)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppzyf.html