Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java forEach lambda抛出concurrentModificationException_Java_Foreach_Java 8 - Fatal编程技术网

Java forEach lambda抛出concurrentModificationException

Java forEach lambda抛出concurrentModificationException,java,foreach,java-8,Java,Foreach,Java 8,下面的方法抛出ConcurrentModificationException的原因可能是什么 static Set<String> setOfAllocAccountsIn(final @NotNull Execution execution) { final Set<String> allocAccounts = new HashSet<>(); execution.legs().forEach(leg -> leg.a

下面的方法抛出
ConcurrentModificationException
的原因可能是什么

static Set<String> setOfAllocAccountsIn(final @NotNull Execution execution) {
        final Set<String> allocAccounts = new HashSet<>();
        execution.legs().forEach(leg -> leg.allocs().forEach(alloc -> {
            if (alloc.account() != null) {
                allocAccounts.add(alloc.account());
            }
        }));
        return allocAccounts;
    }
使用simple
for循环
可以很好地工作。该方法由多个线程使用其自己的执行对象副本调用

使用简单for循环的解决方案:

 static Set<String> setOfAllocAccountsIn(final @NotNull Execution execution) {
        final Set<String> allocAccounts = new HashSet<>();
        for (final ExecutionLeg executionLeg : execution.legs()) {
            for (final ExecutionAlloc executionAlloc : executionLeg.allocs()) {
                if (executionAlloc.account() != null) {
                    allocAccounts.add(executionAlloc.account());
                }
            }
        }
        return allocAccounts;
    }
静态集合集合allocaccountsin(最终@NotNull执行){
最终集合allocAccounts=新HashSet();
for(final ExecutionLeg ExecutionLeg:execution.legs()){
对于(final ExecutionAlloc ExecutionAlloc:executionLeg.allocs()){
if(executionAlloc.account()!=null){
allocAccounts.add(executionAlloc.account());
}
}
}
返回allocAccounts;
}

我觉得它与静态方法有关,它的局部变量由多个线程访问,但根据理论,它将是线程局部变量,不会被共享。给我一些时间写一些简单的例子

您的逻辑可以是这样的:

return execution.legs().stream()
            .flatMap(leg -> leg.allocs().stream())
            .map(executionAlloc -> executionAlloc.account())
            .filter(Objects::nonNull)
            .collect(Collectors.toSet());
  • 您正在
    forEach
    内部使用
    forEach
    (这里我将其替换为
    flatMap
  • 然后检查每个元素的
    alloc.account()
    是否为null(我将其替换为
    filter
  • 然后,如果条件正确,则将其添加到集合中(我将其替换为
    收集

    • 您的逻辑可以是这样的:

      return execution.legs().stream()
                  .flatMap(leg -> leg.allocs().stream())
                  .map(executionAlloc -> executionAlloc.account())
                  .filter(Objects::nonNull)
                  .collect(Collectors.toSet());
      
      • 您正在
        forEach
        内部使用
        forEach
        (这里我将其替换为
        flatMap
      • 然后检查每个元素的
        alloc.account()
        是否为null(我将其替换为
        filter
      • 然后,如果条件正确,则将其添加到集合中(我将其替换为
        收集

      stacktrace说了什么。什么是
      legs
      allocs
      等等?@Ben…让我用一个简单的例子来更新它。如何创建
      Execution
      对象的副本?请发布一个。是否有可能其中一个方法修改了其中一个涉及的集合(例如可能
      executionAlloc.account()
      modifies on of the collection?)stacktrace说了什么。什么是
      legs
      allocs
      等等?@Ben…让我用一个简单的例子来更新它。如何创建
      Execution
      对象的副本?请发布一个。是否有可能其中一个方法修改了其中一个涉及的集合(例如可能
      executionAlloc.account()
      modifies on of the collection?)是的,此代码比OP的代码更干净,但是,进行此更改将如何解决
      ConcurrentModificationException
      ?@Eran老实说,我不知道OP可以从哪里获得
      ConcurrentModificationException
      ,因为
      leg.allocs()
      的结果有一个
      forEach
      方法,它不是数组,而是一个集合,所以它应该是
      leg.allocs().stream()
      而不是
      Stream.of(leg.allocs())
      。此外,如果您在
      过滤器
      之前执行
      .map(executionAlloc->executionAlloc.account())
      ,那么您会获得很多好处,因为这样,谓词就变成了一个简单的
      null
      -检查(
      过滤器(对象::非null)
      ),而不需要重复
      帐户()
      调用。这是正确的@Holger感谢您提供的详细信息,我编辑了我的回答是的,这个代码比OP的代码更干净,但是做这个更改如何解决
      ConcurrentModificationException
      ?@Eran老实说,我不知道OP可以从哪里得到
      ConcurrentModificationException
      ,因为
      leg.allocs()
      的结果有一个
      forEach
      方法,它不是数组,但可能是集合,因此它应该是
      leg.allocs().stream()
      ,而不是
      stream.of(leg.allocs())
      。此外,如果您在
      过滤器
      之前执行
      .map(executionAlloc->executionAlloc.account())
      ,那么您会获得很多好处,因为这样,谓词就变成了一个简单的
      null
      -检查(
      过滤器(对象::非null)
      ),而不需要重复
      帐户()
      调用。这是正确的@Holger感谢您提供的详细信息,我编辑我的答案