`

操作集合抛出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.lang.IllegalStateException: getOutputStream() has already解决办法

    纠结了半天的 java.lang.IllegalStateException: getOutputStream() has already。这个问题困扰了半天,在网上查阅了大量资料 出这个错误一般就是下面2个.....

    ListView后台更新报错:java.lang.IllegalStateException

    java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but...

    Android异常 java.lang.IllegalStateException解决方法

    在Android开发过程中,Java异常`java.lang.IllegalStateException`是一个常见的错误类型,它通常表示程序在不合法或者不合适的状态下尝试执行某项操作。在上述描述中提到了两种特定的`IllegalStateException`情况: ...

    java.lang.IllegalStateException(解决方案).md

    在Java编程中,`java.lang.IllegalStateException`是一种在运行时抛出的异常,它通常发生在某个方法或操作被调用时,所处的状态是不合法或者不允许的情况下。具体来说,当方法被调用时,如果因为某些前置条件未满足...

    java.lang.IllegalStateException: OutputStream already obtain

    标题 "java.lang.IllegalStateException: OutputStream already obtain" 涉及到的是Java编程中的一个常见错误,特别是当处理I/O流时。这个异常通常在尝试获取已经存在的OutputStream实例时抛出,表明该输出流已经被...

    Java异常之—-Caused by: java.lang.IllegalStateException: Method has too many Body parameters

    异常:Caused by: java.lang.IllegalStateException: Method has too many Body parameters Caused by: java.lang.IllegalStateException: Method has too many Body parameters: public abstract ...

    Failed to convert value of type ‘java.lang.String’ to required type ‘java.util.Date’; nested except

    Type 异常报告 消息 Failed to convert ... nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.util.Date': no matching editors or co

    The full error is: java.lang.IllegalState

    如果在子线程中直接操作UI元素,就会抛出`IllegalStateException`。 4. **生命周期管理**:Android应用的组件有明确的生命周期,如Activity和Fragment。如果在不适当的生命周期阶段调用方法,也可能会触发这个错误...

    java.lang.IllegalAccessException(解决方案).md

    `java.lang.IllegalAccessException`的解决需要在理解异常产生原因的基础上,通过合理的设计、正确的编码实践、合适的安全策略和适时的异常处理策略来确保程序的稳定性和安全性。开发者应当避免过度依赖反射机制,...

    关于IllegalStateException: The specified child already has a parent.

    IllegalStateException: The specified child already has a parent.我的博客中有文章讲解

    spring入门好教程

    Spring框架,由Rod Johnson创立并由Interface21公司推广,自诞生以来,它就致力于简化Java企业级应用(J2EE)的开发,提供了一种非侵入式的解决方案,极大地提高了开发效率。它的目标不仅仅是解决单一层次的问题,...

    Invalid name=”com.alibaba.dubbo.config.ProtocolConfig#0″

    使用@EnableDubbo启用dubbo, 配置dubbo.protocol.xxx相关属性,不设置dubbo.protocol.id,启动应用将会抛出异常. java.lang.IllegalStateException: Invalid name=“com.alibaba.dubbo.config.ProtocolConfig#0” ...

    Jnative1.4_java调用动态库所需jar

    然而,有时我们可能需要在Java程序中调用操作系统底层的动态链接库(DLLs on Windows,SOs on Linux,dylibs on macOS),以便利用C、C++等语言编写的高性能代码。这种需求就引出了Java Native Interface(JNI)的...

    xfire访问webservice客户端用到的jar包

    在Java开发中,Web服务(Web Service)是一种标准的接口,允许不同系统之间进行通信,而XFire是早年流行的一款用于构建和消费Web服务的开源框架。它使用SOAP(简单对象访问协议)和XML(可扩展标记语言)作为基础,...

    Android异常处理

    - **为何抛出的异常必须是已检查异常**:`RuntimeException`和`Error`类及其子类不需要显式声明,它们会在程序运行时自动抛出。已检查异常则是由程序员显式抛出的,需要在方法签名中声明。 ##### 3.2 如何抛出异常 ...

    nexus-3.70.1-02-java17-unix.tar.gz

    java.lang.IllegalStateException: The maximum Java version for OrientDb is Java 11. Please check current Java version meets this requirement. 参见: ...

Global site tag (gtag.js) - Google Analytics