2016-11-04 2 views
0

내 솔루션이 다른 질문의 해결책으로 잘못 오인되었다고 생각합니다. 그것은 또한 솔루션이 복제본에 의해 지적 된 것처럼 보이도록 편집되었지만 이것은 분명히 내 문제를 해결하지 못했고 예외 (문제의 표면)를 피할 수있었습니다. 질문을 재개하려는 노력이 쓸모 없기 때문에 나는 here 새 문을 열었습니다.내 코드의 ConcurrentModificationException


나는 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 .... 

자바 코드 :

오류입니다

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 : 내가이 중복 생각하지 않습니다. 일부 테스트에서 얻은 오류는 this 또는 this으로 사라졌습니다. (.add() 접근법을 사용하더라도 몇 가지 이유로 동일한 오류가 발생합니다). 하지만 JSF는 여전히 내가 기대하는 것을 인쇄하지 않습니다.

XHTML의 자바 코드 :

<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 사람의 권리 목록을 반환 다시 정보를 조금 더 내 질문에서 제거 BalusC 코드를 작성 (HashMap<Integer, List<Person>>) 그것을 잘 인쇄합니다. 이 시점에서 저는 두 그룹이 있습니다 : 같은 나이의 3 인과 다른 나이의 다른 인원의 그룹. 을 클릭하면 같은 나이의 3 명 그룹 인을 제거하고 코드를 추적하고 반복자를 사용하여 ConcurrentModificationException을 발생시키지 않고 필요한 모든 사람을 제거합니다. person.getFriends();의 반환 된 목록은 size = 1이며 올바른 값입니다. 그런 다음 ajax 코드가 양식을 렌더링합니다. personController.groupedPersons이 다시 호출되고 예상대로 1 명이 반환됩니다. 나는 이것을 확인했으며 이것은 실제로 내가 기대하는 귀환입니다. 그러나 JSF는 잘못된 #{personG.key} (내가 제거한 것)과 null #{personG.value.size()}을 인쇄합니다.

나는 따라하기가 어려울 수도 있음을 알고 있지만, 이것에 대한 설명을 생각해 낼 수 있습니까?


편집 3 : 이 ... 내가 한 사람이 그룹을 삭제하면이 제거되고 세 사람과 그 다음은 JSF가 올바르게 인쇄 그룹도 재밌죠. 3 명이있는 그룹을 삭제하면 해당 그룹이 삭제되고 JSF가 방금 삭제 한 그룹의 key을 인쇄합니다 (EDIT2에서 말한 것처럼). size()는 null입니다. JSF 사이의 동시성 문제로 인해 목록을 수정하는 동시에 페이지를 새로 고칠 가능성이 있습니까?(이것은 원래 내 걱정이었습니다. ConcurrentModificationException은 Managed Bean 코드 내에서뿐만 아니라 XHTML과 내 관리 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

자바에서는 목록 (friends)을 반복 할 수 없으며 루프에서 요소 (friends.remove(p))를 제거 할 수 없습니다. 이것은 ConcurrentModificationException을 던졌습니다.

removeFriends.add(p);와 접근 방식이 작동합니다 :

당신은 Iterator 대신

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

편집 할 수 있습니다. 이것으로 동시 수정 예외가 발생하지 않습니다. 그러나 기본 목록이 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 (...) '의 경우입니다. 당신이'friends'리스트를 감싸는 것은'새로운 ArrayList (친구)입니다'당신은 잘되어야합니다. – Erik

관련 문제