2016-11-04 17 views
0

私の解決策は間違って別の質問の解決策と誤解されていると思います。それは編集されているので、ソリューションが重複で指摘されているように見えますが、これは明らかに私の問題を解決しなかっただけです。例外(問題の表面)を避けました。質問を再開する私の努力は役に立たなかったので、私はhere新しい1つを開いた。私自身のコードで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 .... 

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); 
     } 
    } 

EDIT:thisは明らかに私の問題を解決していないこと。ただし、エラーを発生させないようにしますが、JSFによって表示される結果は正しくありません。私のリストが完全に更新されていないのに、JSFがリフレッシュしようとしている可能性はありますか?


EDIT2: 私はこれが重複しているとは思いません。いくつかのテストで得たエラーは、thisまたはthisとなりました(何らかの理由で同じエラーが発生したことに注意してください)。しかし、JSFはまだ私が期待しているものを印刷していません。

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私はページを実行する最初の時間、私は再び情報のもう少しで私の質問から削除BalusCコードを書きます(HashMap<Integer, List<Person>>)、うまく印刷します。この時点で私は2つのグループを持っています:同じ年齢の3人のグループと、異なる年齢の別の人。 をクリックすると、同じ年齢の3人のグループを削除し、コードをトレースし、イテレーターを使用して、ConcurrentModificationExceptionを発行せずに必要な人物をすべて削除します。返されたperson.getFriends();のリストは、size = 1です。これは正しいです。次に、ajaxコードがフォームをレンダリングします。 personController.groupedPersonsが再度呼び出され、期待通りに1人が返されます。私は確認して、これは私が実際に期待している返品者です。しかし、JSFは間違った#{personG.key}(私が削除したもの)とヌル#{personG.value.size()}を印刷します。

私はそれに従うのが難しいかもしれないことは知っていますが、これについての説明はありますか?


EDIT 3: これも笑えるです...私は1人を持つグループを削除した場合、それが削除され、その後、JSFプリント3つの者と正しくグループ。私が3人でグループを削除すると、そのグループは削除され、JSFはEDIT2で述べたように、今削除したグループのkeyを印刷し、size()はnullです。 JSF間で並行処理の問題が発生している可能性はありますか?同時にリストを変更しているときにページをリフレッシュしていますか?(これはもともと私の心配で、ConcurrentModificationExceptionはXHTMLと私のマネージドBeanの間の並行性の問題から来ており、マネージドBeanのコード内だけではありませんでした)。それはなぜ私がConcurrentModificationExceptionを得たのかを、リストから削除する代わりにリストに追加したときに説明することができます。

+1

あなたは本当にあなたの質問を編集して、完全にはならないあなたがラップする場合は、あなたのfriendsリストは、あなたが行くために良いことがありnew ArrayList(friends);ですそれを変更。それはすべての答えを無効にし、後世の問題を台無しにする。 – 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がスローされます。 removeFriends.add(p);

あなたのアプローチに動作するはずです:

あなたはIterator代わり

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

EDITを使用することができます。これで同時に変更することはできません。しかし、基本リストがremoveAllをサポートしていない場合は、UnsupportedOperationExceptionで終わることがあります。これは例えばArrays.asList(...)の場合です。

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(friends); 'あなたは良いことがあるはずです。 – Erik

関連する問題