2016-11-04 89 views
0

我认为我的解决方案被错误地解决了另一个问题。它也被编辑过,所以看起来解决方案是重复指向的解决方案,但这显然没有解决我的问题,只是避免了引发的异常(问题的表面)。由于我重新开放这个问题的努力一直没有用,我开了一个新的hereConcurrentModificationException在我自己的代码


我得到一个ConcurrentModificationException,我不能够解决这个问题。所以我从列表中删除了一系列元素,并且出现错误。

这是错误:

04-Nov-2016 15:49:50.488 SEVERE [http-nio-8080-exec-199] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [Faces Servlet] in context with path [/...] threw exception [java.util.ConcurrentModificationException] with root cause 
java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886) 
    at java.util.ArrayList$Itr.next(ArrayList.java:836) 
    at com.ex.PersonController.removeGroup(...) 
    at .... 

的Java代码:

public void removeGroup(int age) { 
    if (person != null) { 
     List<Person> friends = person.getFriends(); 
     List<Person> removeFriends = new ArrayList<>(); 
     if (friends != null) { 
      for (Person p : friends) { 
       if (p.getAge() == age) { 
        removeFriends.add(p); 
       } 
      } 
      friends.removeAll(removeFriends); 
     } 
    } 

编辑: 注意this显然没有解决我的问题。但是,它避免了引发错误,但JSF显示的结果不正确。有没有可能JSF试图刷新,而我的列表没有完全更新?


EDIT2: 我不认为这是一个重复。我的一些测试得到的错误与thisthis(请注意即使使用.add()方法由于某种原因也得到了相同的错误)一起消失了。但JSF仍然没有打印我所期望的。我又写BalusC从我的问题取出更多的信息位代码:

XHTML的Java代码:

<c:forEach items="#{personController.groupedPersons}" var="personG"> 
    <h:commandButton action="#{personController.removeGroup(personG.key)}" type="submit" value="Remove" > 
     <f:ajax render="@form" /> 
    </h:commandButton> 
    #{personG.key} - #{personG.value.size()} 
</c:forEach> 

所以我第一次执行该页面,personController.groupedPersons返回者的右侧列表(a HashMap<Integer, List<Person>>)并打印它就好了。在这一点上,我有2组:一组3人同龄和另一人不同年龄。当我点击删除年龄相同的3人组时,我追踪代码并使用迭代器删除了所有必要的人员,但未提高ConcurrentModificationException。返回的person.getFriends();列表大小= 1,这是正确的。然后ajax代码呈现表单。按预期方式再次调用personController.groupedPersons并返回1个人。我已经证实,这是我实际期望的回报人。但是,然后JSF确实打印了错误的#{personG.key}(我删除的那个)和空#{personG.value.size()}

我知道这可能很难遵循,但你能想到对此的任何解释吗?


编辑3: 这是更有趣...如果我删除有1人组,它被去除,然后将JSF打印正确与3人组。如果我删除了3人的团队,他们将被删除,并且JSF会打印(如我在EDIT2中所述)我刚刚删除,size()为空。在我修改列表的同时,JSF在刷新页面的同时,是否有可能发生并发问题?(这原本是我的担心,ConcurrentModificationException来自XHTML和我的托管bean之间的并发问题,而不仅仅是托管Bean的代码中)。这可以解释为什么我即使在列表中添加了ConcurrentModificationException而不是从列表中删除。

+1

你真的不应该编辑您的问题,完全更改。它使所有的答案无效,并将后代的问题毁于一旦。 – Gray

+0

我没有完全编辑这个问题。正如你可以在历史中看到的那样,它是BalusC。我赞赏编辑,但我仍然认为也许JSF有事可做(也许它不是,这就是为什么他完全删除了所有内容) – user1156544

+0

并发修改异常与JSF无关。 JSF不打印你期望的事实是一个不同的问题(就像你发布的https://stackoverflow.com/questions/40442340/jsf-wrong-display-of-elements-when-iterating-a-map)也是一个'重复'。 JSF按照您使用它的方式进行设计。 – Kukeltje

回答

0

在java中,您不允许迭代列表(friends)并在循环中从中删除元素(friends.remove(p))。这会引发ConcurrentModificationException

您可以使用Iterator代替

Iterator<Person> iterator = friends.iterator(); 
while (iterator.hasNext()) { 
    if (iterator.next().getAge() == age) { 
     iterator.remove(); 
    } 
} 

编辑:

您与removeFriends.add(p);办法应该工作。你不会得到一个并发修改异常。如果您的基础列表不支持removeAll,那么您最终可能会得到UnsupportedOperationException。这例如是Arrays.asList(...)的情况。如果你换你friends名单是new ArrayList(friends);你应该去的好:

public void removeGroup(int age) { 
    if (person != null) { 
    List<Person> friends = new ArrayList<>(person.getFriends()); 
    List<Person> removeFriends = new ArrayList<>(); 
    if (friends != null) { 
     for (Person p : friends) { 
      if (p.getAge() == age) { 
       removeFriends.add(p); 
      } 
     } 
     friends.removeAll(removeFriends); 
    } 
} 

不要忘记设置后,该好友列表:

person.setFriends(friends); 
+0

这是我做的测试之一,你在那里是正确的。但是,我用'removeFriends.add(p);'这种方法怎么样?'对我来说似乎还可以 – user1156544

+0

你的建议避免了这个例外。但是我没有得到正确的结果......似乎代码由于某种原因停止了在中间的循环。或者该列表没有正确显示在xhtml代码中... – user1156544

+0

您使用'removeFriends.add(p);'的方法也应该可以工作。你不会得到一个并发修改异常。如果您的基础列表不支持'removeAll',那么您最终可能会得到'UnsupportedOperationException'。例如'Arrays.asList(...)'就是这种情况。如果你包装你的'朋友'列表是一个'新的ArrayList(朋友)''你应该很好走。 – Erik

相关问题