<List<Map<String,String>>> 删除元素常见的误区以及删除方法

这篇具有很好参考价值的文章主要介绍了<List<Map<String,String>>> 删除元素常见的误区以及删除方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

看到这么标题可能觉得这个真是太easy了,不就remove吗,分分钟搞定。
但结果却出乎意料,下面我们来j简单说说list删除数据可能遇到的坑:
先说明我们可能会遇到的两个问题:
1.java.lang.IndexOutOfBoundsException(索引越界)
2.java.util.ConcurrentModificationException(并发修改异常)

开始测试:

首先初始化一个List<Map<String,String>>

package test02;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/*
 * List<Map<String,String>> 删除元素常见的误区
 * 
 */

public class Test09 {
	public static void main(String[] args) {
		
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		Map<String, String> map1=new HashMap<>();	
		Map<String, String> map2=new HashMap<>();
		Map<String, String> map3=new HashMap<>();
		Map<String, String> map4=new HashMap<>();
		map1.put("key","张三");
		map1.put("value","20");
		map2.put("key","李四");
		map2.put("value","25");
		map3.put("key","王五");
		map3.put("value","30");
		map4.put("key","张三");
		map4.put("value","35");
		list.add(map1);
		list.add(map2);
		list.add(map3);
		list.add(map4);	
		for (int i = 0; i < list.size(); i++) {
			System.out.println("初始化遍历:"+list.get(i));
		}	
	}
}

需求:删除这个list里面,key为张三的数据;

方式一:for i 循环 通过索引使用:list.remove(i)删除;

	    for (int i = 0; i < list.size(); i++) {
			System.out.println("i:"+i);
			System.out.println("len:"+list.size());
			String a = String.valueOf(list.get(i).get("key"));
			if(a.equals("张三")) {
				list.remove(i);
				System.out.println("第"+i+"次循环删除成功");
				System.out.println("删除后长度:"+list.size());
			}
			System.out.println("方式一遍历:"+list.get(i));
		}

出现异常报错java.lang.IndexOutOfBoundsException(索引越界)
原因:每次循环删除元素之后,初始长度已发生变化,在最后一次循环出现越界
打印输出分析:
i:0
len:4
第0次循环删除成功
删除后长度:3
方式一遍历:{value=25, key=李四}
i:1
len:3
方式一遍历:{value=30, key=王五}
i:2
len:3
第2次循环删除成功
删除后长度:2
Exception in thread “main” java.lang.IndexOutOfBoundsException: Index 2 out of bounds for length 2
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
at java.base/java.util.Objects.checkIndex(Objects.java:359)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at test01/test02.Test09.main(Test09.java:62)

方式二:foreach循环:list.remove(map)删除

	   for(Map<String, String> map :list) {
			String a = String.valueOf(map.get("key"));
			if(a.equals("张三")) {
				list.remove(map);
			}
			System.out.println("方式二遍历:"+map);
		}

出现异常报错java.util.ConcurrentModificationException(并发修改异常)
通过源码分析:发现在 next、remove方法中都会调用checkForComodification 方法,
该方法的 作用是判断 modCount != expectedModCount是否相等,
如果不相等则抛出ConcurrentModificationException异常;
当我们调用 list.remove(item)时,对 list 对象的 modCount 值进行了修改;
而 list 对象的迭代器的 expectedModCount 值未进行修改;
所以就抛出ConcurrentModificationException异常!
private class Itr implements Iterator {
int cursor; // 要返回的下一个元素的索引
int lastRet = -1; // 返回的最后一个元素的索引;如果没有就返回-1
int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }

    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}

方式三:Stream流:filter(推荐)

		list = list.stream().filter(e -> (!e.get("key").equals("张三"))).collect(Collectors.toList());
		for (int i = 0; i < list.size(); i++) {
			System.out.println("方式三遍历:"+list.get(i));
		}

输出:
方式三遍历:{value=25, key=李四}
方式三遍历:{value=30, key=王五}

方式四:迭代器iterator的remove方法(使用更加灵活

		Iterator<Map<String, String>> iterator = list.iterator();
		while (iterator.hasNext()){
            Map<String, String> next = iterator.next();
            String key = String.valueOf(next.get(("key")));
            if(key.equals("张三")){
                iterator.remove();
            }
        }
        for (Map<String, String> map : list) {
			System.out.println("方式四遍历:"+map);
		}

输出:
方式四遍历:{value=25, key=李四}
方式四遍历:{value=30, key=王五}

简单总结:

1、用for循环遍历List删除元素时,需要注意索引变化(左移或右移)的问题(不推荐)。
2、List删除元素时,默认按索引删除,而不是对象删除(不推荐)。
3、List删除元素时,为避免陷阱,建议使用Stream流的filter方式(推荐)。
3、List删除元素时,为避免陷阱,建议使用迭代器iterator的remove方式(推荐)。文章来源地址https://www.toymoban.com/news/detail-533503.html

到了这里,关于<List<Map<String,String>>> 删除元素常见的误区以及删除方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python list列表删除元素(4种方法)

    在 Python列表中删除元素主要分为以下 3 种场景: 根据目标元素所在位置的索引进行删除,可以使用 del 或者 pop() 方法; 根据元素本身的值进行删除,可使用列表(list类型)提供的 remove() 方法; 将列表中所有元素全部删除,可使用列表(list类型)提供的 clear() 方法

    2024年02月02日
    浏览(51)
  • <List<Map<String,Object>>>Map中多个属性转成List Map

    举例: 原始数据 :{001=张三, 002=李四, 003=王五, 004=赵六} 目标数据 : {value=张三, key=001} {value=李四, key=002} {value=王五, key=003} {value=赵六, key=004} 输出: 单独封装工具类案例:

    2024年02月11日
    浏览(30)
  • JSON转换List<Map<String, Object>>、Map<String, Object>

    废话就不说了 早上10点研究到现在 获取redis的JSON字符串 String getPalletListNew = redisService.getRedis(“getPalletListNew”, abroad + “” + goodsLevel + “” + startPort + “” + destinationPort + “” + maxTon + “” + minTon); 转换MapString,Object public MapString, Object jsonToMap(String json){ MapString, Object map = new

    2024年02月20日
    浏览(36)
  • List<Map<String, Object>> 转List<T> list map对象转list对象

    我们在处理数据的时候,经常用到map对象转java对象。 要转换的对象 pom文件JSON包 : 如果此篇文章有帮助到您, 希望打大佬们能 关注 、 点赞 、 收藏 、 评论 支持一波,非常感谢大家! 如果有不对的地方请指正!!! 参考1 参考2

    2024年02月13日
    浏览(30)
  • List<Map<String, Object>>

    ListMapString, Object 是一个Java数据结构,它是一个列表(List),其中每个元素都是一个Map。在每个Map中,键(key)是字符串(String),值(value)可以是任何对象(Object)。 这种数据结构通常用于存储和处理一组相关的数据记录。例如,可以使用ListMapString, Object 存储数据库查询结果,其

    2023年04月21日
    浏览(29)
  • <List<Map<String,Object>>>循环List Map获取里面的key和value,进行操作

    输出: Map循环:(Value为Object)

    2024年02月12日
    浏览(30)
  • List<Entity>与Map<String, Entity>互转

    List 转为 MapString, Entity 要将 ListEntity 转换为 MapString, Entity,你需要指定一个属性作为 Map 的键,然后将 List 中的每个实体对象的该属性值作为键,实体对象本身作为值放入 Map 中。以下是一个示例代码: 假设你有一个名为 Entity 的实体类,其中有一个属性名为 id ,你想将 Lis

    2024年04月22日
    浏览(23)
  • postman传参之List<Map<String,Object>>后台是map的集合

    1.控制层   2.业务层接口   3.业务层实现类   4.mapper   5.xml   6.运行结果   7.postman传参格式 [{\\\"id\\\":127,\\\"age\\\":12,\\\"name\\\":30},{\\\"id\\\":232,\\\"age\\\":12,\\\"name\\\":30}] 

    2023年04月20日
    浏览(65)
  • 遍历集合List的五种方法以及如何在遍历集合过程中安全移除元素

    测试数据 1. 普通for循环 普通for循环,通过索引遍历 2. 增强for循环 增强for循环,数组以及所有Collection集合都可以使用增强for循环遍历。遍历集合的实际原理为获取集合的iterator迭代器对象进行迭代遍历。 3. Iterator迭代器遍历 Collection接口继承自Iterable接口,所有Collection集合都

    2024年02月13日
    浏览(34)
  • Java多条件排序使用Comparator和thenComparing【包含排序List<Map<String, String>>】

    在Java中,对一个列表或集合进行排序时,经常需要基于多个条件来排序。幸运的是,Java提供了强大的 Comparator 接口,以及 thenComparing 方法,使我们能够轻松地实现多条件排序。 Comparator 接口是Java用于自定义对象排序的关键接口。它包含了一个 compare 方法,允许我们定义如何

    2024年02月04日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包