`

操作集合抛出java.lang.IllegalStateException异常的原因及其解决思路

    博客分类:
  • java
阅读更多
在Java中经常用到容器类,可以通过迭代器类Iterator来对集合中的元素进行迭代,从而对每个单独的元素进行某种操作,例如:

要删除集合中某一个不满足条件的元素,通过Iterator来删除,首先需要使用next方法迭代出集合中的元素,然后只需要调用remove方法即可。但是如果程序中不小心,造成对一次next方法执行迭代出一个元素,而执行了多于一次的remove删除操作,就会报java.lang.IllegalStateException异常。

其实,原因很显然了,迭代一次只能迭代出集合中的一个元素,而对该一次迭代执行了多次删除,显然就造成集合状态的不正常问题,抛出异常。

下面举一个例子说明一下。

有一个方法实现对集合的过滤功能,代码如下所示:

public void filter(Collection<String> container, Map<Integer, Object> parametersMap) {
  
   this.setFilter(parametersMap);
  
   Iterator<String> it = container.iterator();
   while(it.hasNext()) {
    String s = it.next().trim();
    Iterator<Map.Entry<List<Map<Integer,String>>,Interval<Integer, Integer>>> mapIt = this.hitStageConditionsMap.entrySet().iterator();
    while(mapIt.hasNext()) {
     Map.Entry<List<Map<Integer,String>>,Interval<Integer, Integer>> entry = mapIt.next();
     List<Map<Integer,String>> key = entry.getKey();
     Interval<Integer, Integer> interval = entry.getValue();
     // 调用方法,对s进行一个条件的过滤
     if(!this.passOneCondition(s, key, interval)) { // 如果不满足条件
     it.remove();
     }
    }
   }  
}


程序设计的本意是:

迭代container集合中元素的过程中,首先通过it.next()迭代出一个字符串,然后mapIt里面是条件Map的迭代器实例,由于条件是多重的,需要使用迭代器。当调用this.passOneCondition(s, key, interval)判断不满足其中一个条件的时候,就删除集合container中对应的it迭代出的字符串,而不再进行其它没有进行过滤的条件来执行过滤了。

上面的方法就会抛出java.lang.IllegalStateException异常,如下所示:

java.lang.IllegalStateException
at java.util.HashMap$HashIterator.remove(Unknown Source)
at org.shirdrn.filter.collection.HitStageFilter.filter(HitStageFilter.java:45)
at org.shirdrn.filter.collection.TestHitStageFilter.testHitStageFilter(TestHitStageFilter.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:164)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:120)
at junit.framework.TestSuite.runTest(TestSuite.java:230)
at junit.framework.TestSuite.run(TestSuite.java:225)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)


因为在迭代container集合中元素的过程中,首先通过it.next()迭代出一个字符串,然后mapIt里面是条件Map的一个迭代器实例,当调用this.passOneCondition(s, key, interval)判断不满足其中一个条件的时候,就删除集合container中对应的it迭代出的字符串。如果我们不执行break来终止条件Map的迭代,就会出现多次删除remove集合container中执行一次it.next()迭代出的字符串,所以抛出java.lang.IllegalStateException异常。 所以,在执行集合迭代操作过程中要谨慎小心,上面方法在执行完成remove之后,添加一个break;语句就行了:

public void filter(Collection<String> container, Map<Integer, Object> parametersMap) {
  
   this.setFilter(parametersMap);
  
   Iterator<String> it = container.iterator();
   while(it.hasNext()) {
    String s = it.next().trim();
    Iterator<Map.Entry<List<Map<Integer,String>>,Interval<Integer, Integer>>> mapIt = this.hitStageConditionsMap.entrySet().iterator();
    while(mapIt.hasNext()) {
     Map.Entry<List<Map<Integer,String>>,Interval<Integer, Integer>> entry = mapIt.next();
     List<Map<Integer,String>> key = entry.getKey();
     Interval<Integer, Integer> interval = entry.getValue();
     // 调用方法,对s进行一个条件的过滤
     if(!this.passOneCondition(s, key, interval)) { // 如果不满足条件
     it.remove();
     break;
     }
    }
   }  
}

分享到:
评论

相关推荐

    JAVA资格认证:SCJP310-055中文

    `try`块中放置可能抛出异常的代码,`catch`块用于捕捉异常,`finally`块无论是否发生异常都会执行。 - **异常分类**: 异常可以分为运行时异常(`RuntimeException`)、受检异常(`Exception`)和错误(`Error`)。...

    超级有影响力霸气的Java面试题大全文档

    java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 9、说出Servlet的生命周期,并说出Servlet和CGI的区别。  Servlet被服务器实例化后,容器运行其init方法...

    Iterable和Iterator的关系

    如果在没有调用`next()`的情况下调用`remove()`,则会抛出`IllegalStateException`。 使用`Iterator`进行遍历时,通常遵循以下模式: ```java Iterator&lt;T&gt; iterator = collection.iterator(); while (iterator....

Global site tag (gtag.js) - Google Analytics