【LeetCode】HashMap报ConcurrentModificationException异常

项目场景:

        题目编号是387. 字符串中的第一个唯一字符

        给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。


问题描述

        我的想法是对字符串s的每一个不同字符出现的次数来建立一个HashMap,然后遍历这个HashMap的key,删除出现次数大于1的key值,然后再遍历剩下的key值,比较它们在字符串中的索引大小,返回最小的索引值,不能直接返回第一个出现的key值对应的索引,因为HashMap的key值经过了Hash计算后,不一定就是按照插入顺序进行排序的。具体代码如下:

HashMap<Character,Integer> charMap = new HashMap<>();

        for (int i=0; i<s.length(); i++) {
            charMap.put(s.charAt(i), charMap.getOrDefault(s.charAt(i),0)+1);
        }
        
        for (Character c:charMap.keySet()) {
            if (charMap.get(c) > 1) {
                charMap.remove(c);
            }
        }

        if (charMap.size() == 0) {
            return -1;
        }

        int minIndex = s.length();
        for (Character c:charMap.keySet()) {
            minIndex = Math.min(minIndex,s.indexOf(c));
        }

        return minIndex;

        但执行程序时,报下面的错误。

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
    at java.util.HashMap$KeyIterator.next(HashMap.java:1461)
    at easyQuestion.AAAATempTest.firstUniqChar(AAAATempTest.java:15)
    at MainApp.main(MainApp.java:69)


原因分析:

        在for循环前面和里面增加一个打印。

        System.out.println(charMap);
        for (Character c:charMap.keySet()) {
            System.out.println(c);
            if (charMap.get(c) > 1) {
                charMap.remove(c);
            }
        }

        输出如下:

{c=1, t=1, d=1, e=3, l=1, o=1}
c
t
d
e

        可以看到每次都是在e之后报错, 那说明问题就是出在e这个字母这了,也就是说e的出现次数大于1,导致HashMap进行remove,导致错误的发生了。看错误报告本身也可以看出是找不到nextNode了。


解决方案:

        针对于这个题目的解决方案有一种更简便的方法,就是建立HashMap之后,遍历字符串s,然后直接返回第一个HashMap中值为1的。

    public int firstUniqChar(String s) {

        HashMap<Character,Integer> charMap = new HashMap<>();

        for (int i=0; i<s.length(); i++) {
            charMap.put(s.charAt(i), charMap.getOrDefault(s.charAt(i),0)+1);
        }

        for (int i=0; i<s.length(); i++) {
            if (charMap.get(s.charAt(i)) == 1) {
                return i;
            }
        }

        return -1;
    }

        针对于其它问题的解决方案就是,你不能一边循环key值,一边删除元素。可以通过增加一个List进行存储key,不直接删除元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xanadw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值