300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Java集合如何遍历删除指定元素

Java集合如何遍历删除指定元素

时间:2023-12-07 17:58:22

相关推荐

Java集合如何遍历删除指定元素

目录

1、删除List

2、删除Set

3、删除Map

注意事项:

1、删除List

public class ListDemo {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("张三");list.add("李四");list.add("王五");list.add("赵六");list.forEach(System.out::println);for(String str : list) {if ("李四".equals(str)) {list.remove(str);}}list.forEach(s -> {System.out.println("第1次删除后:" + list);});}}

以上代码运行会发生并发修改异常ConcurrentModificationException,正确的方式是:

public class ListExample {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("张三");list.add("李四");list.add("王五");list.add("赵六");System.out.println(list);// 方法1:迭代器遍历Iterator<String> iterator = list.iterator();while(iterator.hasNext()) {String s = iterator.next();if ("李四".equals(s)) {iterator.remove();}}System.out.println("第1次删除后:" + list);// 方法2:使用集合的removeIf()方法list.removeIf(new Predicate<String>() {@Overridepublic boolean test(String s) {return "王五".equals(s);}});System.out.println("第2次删除后:" + list);}}

2、删除Set

同样,Set也不能通过foreach删除,否则发生异常

public class SetExample {public static void main(String[] args) {Set<String> set = new HashSet<>();set.add("张三");set.add("李四");set.add("王五");System.out.println(set);// 此处会发生并发修改异常for(String str : set) {if ("张三".equals(str)) {set.remove(str);}}System.out.println("第1次删除后:" + set);set.removeIf("李四"::equals);System.out.println("第2次删除后:" + set);}}

3、删除Map

public static void main(String[] args) {Map<Integer, String> map = new HashMap();map.put(1, "张三");map.put(2, "李四");map.put(3, "王五");map.put(4, "赵六");map.forEach((k, v) -> System.out.println(k + "," + v));Iterator<Map.Entry<Integer, String>> iterator = map.entrySet().iterator();while(iterator.hasNext()) {Map.Entry<Integer, String> entry = iterator.next();Integer key = entry.getKey();if (key == 1) {iterator.remove();}}System.out.println(map);}

注意事项:

使用普通for循环删除list里面的元素会有bug,当删除一个元素时,list的长度会减1,被删除元素的后一个元素会向前移动,导致只删了一部分符合条件的元素。

public class ListExample {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("张三");list.add("张三");list.add("李四");list.add("王五");list.add("赵六");System.out.println("删除前:" + list);for (int i = 0; i < list.size(); i++) {String s = list.get(i);if ("张三".equals(s)) {list.remove(s);}}System.out.println("删除后:" + list);}}

以上代码的运行结果为:

删除前:[张三, 张三, 李四, 王五, 赵六]

删除后:[张三, 李四, 王五, 赵六]

原因是:

第一轮循环,i = 0,会删除第一个张三,删除之后只剩四个元素[张三, 李四, 王五, 赵六]

第二轮循环,i = 1,从第二个元素(也就是“李四”)开始判断

以上代码可以简单的改成如下,每次都比较第一个元素

public class ListExample {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("张三");list.add("张三");list.add("李四");list.add("王五");list.add("赵六");System.out.println("删除前:" + list);for (int i = 0; i < list.size(); i++) {String s = list.get(0);if ("张三".equals(s)) {list.remove(s);}}System.out.println("删除后:" + list);}}

事实上Collection的removeIf()方法的实现也是通过Iterator的romove()方法删除元素,源码如下:

default boolean removeIf(Predicate<? super E> filter) {Objects.requireNonNull(filter);boolean removed = false;final Iterator<E> each = iterator();while (each.hasNext()) {if (filter.test(each.next())) {each.remove();removed = true;}}return removed;}

答疑环节:

那有童鞋就要问了,foreach遍历删除会发生异常,为什么普通for循环就能正常运行呢?

因为foreach也会被编译成迭代器遍历的方式,只不过调用的是集合的remove()方法,没有调用迭代器的remove()导致的异常。

foreach编译前:

public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("张三");list.add("张三");list.add("李四");list.add("王五");list.add("赵六");System.out.println("删除前:" + list);for (String s : list) {if ("张三".equals(s)) {list.remove(s);}}System.out.println("删除后:" + list);}

foreach编译后:

public static void main(String[] args) {List<String> list = new ArrayList();list.add("张三");list.add("张三");list.add("李四");list.add("王五");list.add("赵六");System.out.println("删除前:" + list);Iterator var2 = list.iterator();while(var2.hasNext()) {String s = (String)var2.next();if ("张三".equals(s)) {list.remove(s);}}System.out.println("删除后:" + list);}

如果还想更深入了解为什么会发生异常,可以参考文章Java集合的快速失败原则

文章总结:

使用迭代器的remove()方法删除就可以了

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。