【集合】循环删除 ArrayList 集合中的重复元素

普通for循环正序删除

public static void remove(List<T> list, T s) {
  for (int i = 0; i < list.size(); i++) {
    if (list.get(i).equals(s)) {
      list.remove(list.get(i));
    }
  }
}

结论:删除过程中元素向左移动,不能删除重复的元素。

普通for循环倒序删除

public static void remove(List<T> list, T s) {
   for (int i = list.size() - 1; i >= 0; i--) {
     if (list.get(i).equals(s)) {
       list.remove(list.get(i));
     }
   }
 }

结论:删除过程中元素向左移动,可以删除重复的元素。

增强for循环删除

public static void remove(List<T> list, T s) {
   for (T o : list) {
     if (o.equals(s)) {
       list.remove(o);
     }
   }
 }

结论:使用ArrayList的remove()方法删除,产生并发修改异常ConcurrentModificationException

迭代器遍历,使用List集合的remove方法删除

public static void remove(List<T> list, T s) {
   Iterator<T> iterator = list.iterator();
   while (iterator.hasNext()) {
     if (iterator.next().equals(s)) {
       list.remove(iterator.next());
     }
   }
 }

结论:使用ArrayList的remove()方法删除,产生并发修改异常ConcurrentModificationException

迭代器,使用迭代器的remove方法删除

public static void remove(List<T> list, T s) {
  Iterator<T> iterator = list.iterator();
  while (iterator.hasNext()) {
    if (iterator.next().equals(s)) {
      iterator.remove();
    }
  }
}

结论:使用迭代器的remove()方法删除,可以删除重复的元素,但不推荐使用。

源码分析

根据索引删除

public E remove(int index) {
   // 检查索引是否越界
   rangeCheck(index);
   // 列表被修改(add和remove操作)次数+1
   modCount++;
   // 保存要删除的值
   E oldValue = elementData(index);
   // 计算移动的元素数量
   int numMoved = size - index - 1;
   if (numMoved > 0)
     // 删除位置后面的元素向左移动,这里是用数组拷贝实现的
       System.arraycopy(elementData, index+1, elementData, index, numMoved);
   // 将最后一个位置引用设为null,使垃圾回收器回收这块内存
   elementData[--size] = null; // clear to let GC do its work
   // 返回删除元素的值
   return oldValue;
}

private void rangeCheck(int index) {
       if (index >= size)
           throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

根据元素删除

public boolean remove(Object o) {
   if (o == null) {
       for (int index = 0; index < size; index++)
           if (elementData[index] == null) {
               fastRemove(index);
               return true;
           }
   } else {
       for (int index = 0; index < size; index++)
           if (o.equals(elementData[index])) {
               fastRemove(index);
               return true;
           }
   }
   return false;
}

private void fastRemove(int index) {
   // 修改次数+1
   modCount++;
   // 计算移动的元素数量
   int numMoved = size - index - 1;
   if (numMoved > 0)
       // 数组拷贝实现元素向左移动
       System.arraycopy(elementData, index+1, elementData, index, numMoved);
   // 将最后一个位置引用设为null
   elementData[--size] = null; // clear to let GC do its work
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值