ArrayList在执行remove方法时遇到的问题

Love The Way You Lie 2022-06-17 13:51 264阅读 0赞

关于ArrayList删除操作中遇到的一个问题

代码是(略去类和main函数,只上核心代码):

  1. List list = new ArrayList<>();
  2. for(int i =0 ;i<10;i++){
  3. list.add(i);
  4. }
  5. for(int i = 0 ; i<10;i++){
  6. System.out.println(list.size());
  7. list.remove(i);
  8. }

运行结果是:

  1. 10
  2. 9
  3. 8
  4. 7
  5. 6
  6. 5
  7. Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
  8. at java.util.ArrayList.rangeCheck(Unknown Source)
  9. at java.util.ArrayList.remove(Unknown Source)
  10. at cn.zyy.designmode.thread0427.MainTest.main(MainTest.java:21)

通过查看源码 两个重写的 remove 方法:

(1)E remove(intindex):

  1. public E remove(int index) {
  2. //检查index是否在list的容量大小范围之内,否则抛出异常
  3. rangeCheck(index);
  4. //modCount表示list的修改次数(此处可以忽略这个参数)
  5. modCount++;
  6. //Arralist底层是一个数组实现,elementData表示实现list的数组
  7. E oldValue = elementData(index);
  8. //size表示list的容量大小,以下两行代码表示,执行删除操作时,即:删除位置之后的数据全部前移一个位置
  9. int numMoved = size - index - 1;
  10. if (numMoved > 0)
  11. System.arraycopy(elementData, index+1, elementData, index,
  12. numMoved);
  13. //最后将带删除元素置空,等到GC清除
  14. elementData[--size] = null; // Let gc do its work
  15. return oldValue;
  16. }
  17. private void rangeCheck(int index) {
  18. if (index >= size)
  19. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  20. }

根据源码,可以分析出我的错误原因,当0==5以后,由于size的值已经不满足index<size这个条件,所以就爆出java.lang.IndexOutOfBoundsException的错误。

解决办法: list .remove(i) 改成 list .remove(0) 。

(2)顺便了解下booleanremove(Object o):

  1. public boolean remove(Object o) {
  2. //分成两种情况考虑:参数是null或者不是null
  3. if (o == null) {
  4. //循环遍历实现list的数组,查找所有值是null的数组元素,然后执行fastRemove方法。
  5. for (int index = 0; index < size; index++)
  6. if (elementData[index] == null) {
  7. fastRemove(index);
  8. return true;
  9. }
  10. } else {
  11. //循环遍历实现list的数组,查找所有值是o的数组元素,然后执行fastRemove方法。
  12. for (int index = 0; index < size; index++)
  13. if (o.equals(elementData[index])) {
  14. fastRemove(index);
  15. return true;
  16. }
  17. }
  18. return false;
  19. }
  20. //根据数组下标进行数组元素删除(类似于E remove(int index)方法,只是不加异常判断而已)
  21. private void fastRemove(int index) {
  22. modCount++;
  23. int numMoved = size - index - 1;
  24. if (numMoved > 0)
  25. System.arraycopy(elementData, index+1, elementData, index,
  26. numMoved);
  27. elementData[--size] = null; // Let gc do its work
  28. }

发表评论

表情:
评论列表 (有 0 条评论,264人围观)

还没有评论,来说两句吧...

相关阅读