目录
前言
实现方式
1.普通实现
1.1 使用【for循环】 方式
1.2 使用【迭代器】方式
2.jdk1.8新增功能实现
2.1 使用【lambda表达式】方式
2.2 使用【stream流】方式
注意事项
1. 使用【for循环】 方式
2. 不能使用增强for遍历修改元素
总结
前言
分享几种从List中移除元素的常用方法,【注意事项】尤其重要,很容易踩坑。
实现方式
场景:移除List集合中所有的偶数。
1.普通实现
1.1 使用【for循环】 方式
- 代码示例如下:
/**
* 使用【for循环】在遍历过程中移除元素
* @param list
* @return
*/
public static List<Integer> removeMethod6(List<Integer> list) {
for (int i = list.size() - 1; i >= 0; i--) {
Integer integer = list.get(i);
if (0 == integer % 2) {
list.remove(i);
}
}
return list;
}
1.2 使用【迭代器】方式
- 【while循环】代码示例如下:
/**
* 使用迭代器在遍历过程中移除元素
* @param list
* @return
*/
public static List<Integer> removeMethod(List<Integer> list) {
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer integer = iterator.next();
if (0 == integer % 2) {
iterator.remove();
}
}
return list;
}
- 【for循环】代码示例如下:
/**
* 使用【增强for】在遍历过程中移除元素
* @param list
* @return
*/
public static List<Integer> removeMethod2(List<Integer> list) {
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Integer integer = (Integer) iterator.next();
if (0 == integer % 2) {
iterator.remove();
}
}
return list;
}
2.jdk1.8新增功能实现
2.1 使用【lambda表达式】方式
- 代码示例如下:
/**
* 使用【lambda表达式】移除元素
* @param list
* @return
*/
public static List<Integer> removeMethod3(List<Integer> list) {
list.removeIf(integer -> 0 == integer % 2);
return list;
}
2.2 使用【stream流】方式
- 代码示例如下:
/**
* 使用【stream流】移除元素
* @param list
* @return
*/
public static List<Integer> removeMethod4(List<Integer> list) {
list = list.stream().filter(integer -> 0 == integer % 2).collect(Collectors.toList());
return list;
}
注意事项
1. 使用【for循环】 方式
在1.1中,为什么要从集合的最后往前遍历呢?
因为List底层是一个动态数组,从数组中移除一个非末尾的元素,该元素后面的元素都会动态的往前移动。如果从前往后遍历,那每移除一个元素,当前索引的元素就会发生改变,会导致有些元素遍历不到,影响结果的正确性。 例如:
package com.zhy.coll;
import java.util.ArrayList;
import java.util.List;
public class TestList {
/**
* 初始化List集合
* @return
*/
public static List<Integer> initList(List<Integer> list){
for(int i = 0; i < 10; i++) {
Integer integer = (int)(Math.random() * 100);
list.add(integer);
}
return list;
}
/**
* 使用迭代器在遍历过程中移除元素
* @param list
* @return
*/
public static List<Integer> removeMethod5(List<Integer> list) {
for (int i = 0; i < list.size(); i++) {
Integer integer = list.get(i);
if (0 == integer % 2) {
list.remove(i);
}
}
return list;
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
initList(list);
List<Integer> list2 = new ArrayList<Integer>();
list2.addAll(list);
System.out.println("初始化集合:\n\t" + list2);
//方式五
list2.clear();
list2.addAll(list);
System.out.println("使用【for循环】从前往后遍历数组,并移除集合中所有的偶数:\n\t" + removeMethod5(list2));
}
}
输出结果:发现并没有正确移除集合中所有的偶数。
注:所以使用这种方式的话,一定要特别注意,用倒序遍历索引的方式。
2. 不能使用增强for遍历修改元素
增强for只能遍历集合元素,不能对集合元素个数进行修改(包括增加和删除)会编译报错。
总结
使用普通实现方式,一目了然,但是代码行数比较多;使用1.8新增功能实现,代码就会简洁,但是在团队配合开发的场景中,如果没有了解过1.8新增特性的,可能可读性不强。方式各有优劣势,根据需求择优选择。