2017-08-12 12 views
0

編集:私の間違いを理解しています。なぜか私は考えていませんでしたが、previousItems.add(p);が実行された後、それはfor loopから出ていました。私は追加して解決しましたbreakサーブレット内のjava.util.ConcurrentModificationException

他の質問については、解決策を得るのに役立たなかった。

私はServletを持っています。これは、別のページからカートにアイテムを追加するときに呼び出されます。

私はを持っています。私はリストを繰り返して、私がリストにすでに追加しようとしているものと同じ製品であるかどうかを確認します。それがすでに存在する場合はその数量を更新します。そうでない場合は、リストに新しい製品を追加します。

いつも同じ製品を追加するとすべて問題なく、別の製品を追加すると例外が発生します。だから私はコード内の問題はelseの後にあると思う(「This」とコメントされている)。これは、製品が異なる場合に実行されるためである。

@WebServlet(name = "AddCart", urlPatterns = {"/AddCart"}) 
public class AddCart extends HttpServlet { 

    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     HttpSession session = request.getSession(); 
     ArrayList<Product> previousItems = (ArrayList<Product>) session.getAttribute("previousItems"); 
     Product p = (Product) session.getAttribute("currentProduct"); 
     if (previousItems == null) { 
      previousItems = new ArrayList<Product>(); 
     } 

      if (p != null) { 
       if (previousItems.size()>0) { 
        for (Product p1 : previousItems) { 
         if (p1.getId() == p.getId()) { 
          p1.addQuantity(); 
         } else { //This 
          previousItems.add(p); 
         } 
        } 
       } else { 
        previousItems.add(p); 
       } 
      } 

     session.setAttribute("previousItems", previousItems); 
     response.sendRedirect("cart.jsp"); 
    } 
} 

また、同じ例外の​​も削除しようとしました。

そして、これはHTTP Status 500 – Internal Server Error

java.util.ConcurrentModificationExceptionが

java.util.ArrayListの$ Itr.checkForComodification(ArrayList.java:901) java.util.ArrayListの$ Itrがあります.next(ArrayList.java:851) servlets.AddCart.doGet(AddCart.java:36) javax.servlet.http.HttpServlet.service(HttpServlet.java:635) javax.servlet.http.HttpServlet.service( HttpServlet.java:742)あなたがforループのArrayList内部を変更するとorg.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

+0

エラーメッセージが表示されましたか? – GhostCat

+0

はい、私は助けませんでした。私は既にListIteratorsを試してみました。私は解決するために1時間以上を試みてきました。問題はIteratorだとわかっていますが、サーブレットを呼び出すとリストの先頭に再びセットされていませんか? – Mattia

+1

それはそれを反復しながらリストを変更しないことについて何かを教えてくれるでしょう... – GhostCat

答えて

3

あなたは拡張forループで反復されているリストに項目を追加することはできません。これは、リストの内部状態を変更しているためです。これを処理することは可能ですが、ほとんどのイテレータ実装では、膨大な大部分のユースケースで簡単に処理できるように、基礎となるコレクションの状態変更を処理しません。

の代わりにこの:

for (Product p1 : previousItems) { 
    previousItems.add(p); // Simplified 
} 

あなたはpは、後のリストにある別のリストに入れて、その後、反復後、そのリストを追加したい場合は、次の

List<Product> other = new ArrayList<>(); 
for (Product p1 : previousItems) { 
    other.add(p); 
} 
previousItems.addAll(other); 
+1

私はこれが最初のようなものだと思っています。代わりにコメントを返すことを控えてください。例えば、重複がたくさんあるはずです。通常、それは他の方法で動作しました。しかし、良い正確な答え。 – GhostCat

1

この例外は、期待されています。内部的には、forループではIteratorが使用され、反復処理中はスレッドセーフではないコレクションの変更は許可されません。あなたはthisの記事を読むことができます。

しかし、私はあなたのロジック以下の方法を変更することをお勧めしたい:

if (p != null) { 
    // Check if previousItems already contains the product 
    if (!previousItems.contains(p)) { 
    // If it doesn't, add the product 
    previousItems.add(p); 
    } 
} 
+0

はい、とても簡単でした。私は 'forループ'の中に 'previousItems.add(p)'の後に 'break'を追加しました。あなたのソリューションを使用する場合、私はまだ製品を見つけるために 'forループ'を使用する必要があります。だから、もし私が好きなら、それは良いですか? – Mattia

1

あなたが更新することはできません。あなたが反復処理中であることを示すリスト、この原因ConcurrentModificationException

for (Product p1 : previousItems) { 
    previousItems.add(p); //you cant update the previousItems list here 
} 

代わりに、あなたは何ができるかです:

ArrayList<Product> auxList = new ArrayList<>(); 
for (Product p1 : previousItems) { 
    //... 
    //else... 
     auxList.add(p); 
} 

以降:

previousItems.addAll(auxList); 
0

使用、CopyOnWriteArrayListとの代わりに、ArrayListのあなただけのConcurrentModificationExceptionを回避したい場合。

関連する問題