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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/KLH_BAHK/article/details/88775474

普通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
}

猜你喜欢

转载自blog.csdn.net/KLH_BAHK/article/details/88775474