【问题标题】:How to avoid Java.util.IllegalStateException in the following code?如何在以下代码中避免 Java.util.IllegalStateException?
【发布时间】:2011-12-01 01:14:37
【问题描述】:

我有一个包含重复值的整数列表。我需要做的是找到重复的整数,添加它们的值,然后通过删除找到的重复项将结果添加到列表中。这是我正在做的事情:

List<Integer> list1 = new ArrayList<Integer>();
    list1.add(2);
    list1.add(5);
    list1.add(3);
    list1.add(5);
    list1.add(4);

    List<Integer> list2 = new ArrayList<Integer>();
    Iterator<Integer> it = list1.iterator();
    while (it.hasNext()) {
        Integer int1 = it.next();
        if (list2.isEmpty()) {
            list2.add(int1);
            it.remove();
        } else {
            ListIterator<Integer> it2 = list2.listIterator();
            while (it2.hasNext()) {
                Integer int2 = it2.next(); 
                if (int2 != int1) {
                    it2.add(int1);
                    it.remove();// I get exception here

                } else {                        
                    it2.remove();
                    it.remove();
                    Integer newint = int1 + int2;
                    it2.add(newint);
                }                   
            }
        }
    }       
    for(Integer in : list2){
        System.out.println(in);
    }

输出应该类似于
2
10
3
4

感谢您的宝贵时间。

【问题讨论】:

  • 作为旁注,建议参考接口而不是具体实现(即编写 List list1 = new ArrayList();)

标签: java exception collections iterator arraylist


【解决方案1】:

正如其他发帖人所说,迭代时不能删除。尽管存在“技巧”,但在迭代时弄乱集合是获得奇怪的运行时错误的可靠方法。

不管怎样,你在这个问题上工作太努力了。

这是一个快速而肮脏的解决方案,只需要一小部分代码:

private List<Integer> sumAndUniqDuplicates(List<Integer> list) {
    LinkedHashMap<Integer, Integer> lookup = new LinkedHashMap<Integer, Integer>();
    for (Integer value : list) {
        Integer prevValue = lookup.get(value);
        prevValue = (prevValue == null) ? 0 : prevValue;
        lookup.put(value, prevValue + value);
    }
    return new ArrayList<Integer>(lookup.values());
}

【讨论】:

    【解决方案2】:

    如果您被允许使用地图,您可以执行以下简单操作(传入伪代码):

    create empty Map m
    for each Integer x in list1 do
        if m does not contain key x 
            m.put(x, x)
        else
            m.put(x, m.get(x) + x)
        endif
    done
    

    您的结果是 m 的值(这是一个集合)。

    编辑:你说你有 LatLng 而不是 Integers - 我不知道 LatLng 但在快速谷歌之后我会在下面拍摄,假设你想“添加”提高你的 LatLng 点数:

    create empty Map<LatLng, LatLng> m
    for each LatLng x in list1 do
        if not m.containsKey(x) 
            m.put(x, x)
        else
            m.put(x, LatLng.newInstance(m.get(x).getLatitude() + x.getLatitude(),
                                        m.get(x).getLongitude() + x.getLongitude()))
        endif
    done
    

    我在这里看到的唯一问题是这个m.containsKey(x) 依赖于equals 的正确实现,我在阅读this 后不确定

    【讨论】:

    • 问题是我不能使用地图,我实际上正在使用谷歌地图,我有 LatLng 点而不是 Integer,所以当我用 LatLng 点在地图上获取一些东西时它返回 null :(
    • 这是我尝试过的,它在覆盖equals方法后起作用。感谢您的回答。
    【解决方案3】:

    这是因为您删除了两次相同的元素。第一次在if(list2.isEmpty()) 中(因为list2 开头是空的,紧随其后的是else 正文。

    【讨论】:

    • 关于如何克服这个问题的任何建议?即使我没有第一次删除,我的意思是在 list2.isEmpty 块中,它仍然给我错误。
    【解决方案4】:

    来自remove 方法的文档:

    从底层集合中移除迭代器返回的最后一个元素(可选操作)。 每次调用 next 只能调用一次此方法。

    【讨论】:

      【解决方案5】:

      您不能两次删除当前元素。你需要重新思考你的逻辑。

      【讨论】:

      • 关于如何实现它有什么建议吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-05
      • 2018-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-03
      • 1970-01-01
      相关资源
      最近更新 更多