1

各要素にキーと値( ArrayList<dataStructure>)があるリンクリストがあります。同じキーを持つ要素をマージしたい。

    Iterator<CElem> oItr = linkedList.iterator();
    {
        while (oItr.hasNext())
        {
            CElem outer = oItr.next();              
            Iterator<CElem> iItr = linkedList.iterator();
            {
                while (iItr.hasNext())
                {
                    CElem inner = iItr.next();
                    if (outer.equals(inner))
                        continue;

                    if (outer.getKey().equals(inner.getKey()))
                    {
                        outer.getValues().addAll(inner.getValues());
                        iItr.remove();
                    }
                }
            }
        }
    }

イテレータ remove メソッドを使用していますが、java.util.ConcurrentModificationException. これを取り除くために何を変更する必要があります。

4

5 に答える 5

2

イテレータの 1 つで要素を削除すると、2 番目のイテレータはこの削除を認識せず、ConcurrentModificationExceptionスローされます

ところで:

キーと値のペアを持つリストの代わりに、マルチマップを使用することを検討する必要があります

于 2013-08-13T16:44:19.480 に答える
1

両方のイテレータがリンクされたリストをトラバースしています

Iterator<CElem> oItr = linkedList.iterator();
....
Iterator<CElem> iItr = linkedList.iterator();

おそらくiItrは内部配列リスト用であるべきですか?

回答の上の更新スクラッチ私は質問を読み違えました。ただし、課題は、リストをトラバースする 2 つのイテレーターがあることです。そのため、一方のイテレーターの remove() メソッドを使用している間、もう一方は同時変更を検出します。

通常、リストから重複を削除するには、セット (HashSet など) を介してそれらを実行できますが、リストのメンバー全体ではなく、キーの重複のみであるため、これは機能しません。

重複したキーとその値を別のリストで見つけてキャプチャし、別のステップとして重複をマージして削除するというアプローチを取ります。

于 2013-08-13T16:42:54.947 に答える
1

削除する要素を別のリストに追加し、最後にそのリストをループしてこれらの要素を削除します。

または、マップ/セットを使用します。

于 2013-08-13T16:50:26.323 に答える
0

これは機能しますか?

 Iterator<CElem> oItr = linkedList.iterator();
    {
        while (oItr.hasNext())
        {
            CElem outer = oItr.next();              
            Iterator<CElem> iItr = linkedList.iterator();
            {
                while (iItr.hasNext())
                {
                    CElem inner = iItr.next();
                    if (outer.equals(inner))
                        continue;

                    if (outer.getKey().equals(inner.getKey()))
                    {
                        inner.getValues().addAll(outer.getValues());
                        outer.remove();
                        break;
                    }
                }
            }
        }
    }
于 2013-08-13T17:11:24.130 に答える
0

問題は、 を使用するiItr.remove()とリストが変更されることです。iItr何が変更されたかを知っているので満足していますが、そうでoItrはありません。これには、次の 3 つの解決策があります。

  1. 並行リストに切り替えます (例- ただし、これに関する警告については、Java のロックフリー並行リンク リストのConcurrentLinkedQueue回答を参照してください)。
  2. セット構造に切り替えます。たとえばTreeSet、アイテムを自動的に一意に保ちます (ただし、順序は保持されません)。
  3. それらの1つから削除した後、他のイテレータを使用しないことを確認してください-削除する要素を切り替えることでこれを行うことができます。つまり、次のように変更iItr.remove()します。

     oItr.remove();
     break;
    

これにより、後続のキーではなく、各キーの最初のインスタンスが削除されます。これは、必要な動作ではない可能性があります。その場合は、リストを逆方向に繰り返してみることができます。

于 2013-08-13T16:50:24.880 に答える