5

質問1:

ArrayListのサイズを指定するのは理にかなっていますか?リストに含まれる要素の数はわかっています。事前にサイズを指定するのが適切か、それとも問題ではありません。

List<String> list = new ArrayList<String>(1);
list.add("Hello");

List<String> newList = new ArrayList<String>();
newList.add("Hello");

質問2:

java.util.ConcurrentModificationExceptionは、同じコレクションを反復処理しているときにコレクションを操作(追加、削除)すると発生します。Does that mean there is a thread which is modifying the ArrayList and another Thread iterating the same object.

質問3

リストをロックする方法を教えてもらえますか?

4

4 に答える 4

8
  1. 多くのアイテムを追加する場合は重要です。これは、コレクションが進行するときに内部バッファーをコピーし続ける必要がないことを意味します。小さなリストでは、大きな違いはありません。サイズを指定していないことに注意してくださいArrayList-初期容量を指定しています:

    List<String> list = new ArrayList<String>(10000);
    System.out.println(list.size()); // 0
    

    サイズを変更するには、アイテムを追加する必要がありますが、内部でコピーを実行する前に、容量までアイテムを追加できます。

  2. いいえ、余分なスレッドを含める必要はありません。これは、コレクションを繰り返し処理しているときにコレクションを変更したことを意味します。これは非常に簡単に単一のスレッドに含めることができます。

    for (String item : items) {
        items.add("Foo"); // The next iteration step will fail.
    }
    
  3. あなたはより多くの文脈を与える必要があるでしょう。通常、リストに対していくつかの操作を実行しているときにロックを取得する方が理にかなっています。

于 2012-11-10T18:07:41.583 に答える
1
  1. リストが大きくなる場合は、はい、初期サイズを宣言する価値があります。なんで?ArrayListを作成するとき、その初期サイズは多くの場合〜10であるためです。新しいアイテムを追加し、初期サイズが十分でない場合、ArrayListにより多くのメモリが割り当てられ、すべての要素が再配置されますが、時間がかかります。

  2. いいえ、別のスレッドは必要ありません。この例外は、リストを反復処理し、ループ本体でその要素を追加または削除した場合に発生する可能性があります。次に、イテレータを使用する必要があります。

  3. リストをロックするとはどういう意味ですか?スレッドセーフにしたいですか、それとも要素の追加/削除を無効にしたいですか?2番目のケースでは、unmodifiableCollectionでメソッドを使用しjava.util.Collectionsます。

于 2012-11-10T18:07:30.613 に答える
1

Q1:これはArrayListがどのように見えるかです

public ArrayList{
    private int[] elementData;
    private int size;
}

ArrayListを作成すると、配列のサイズが自動的に初期化されます。スペースが足りなくなると、サイズは自動的に元のサイズの1.5倍に調整されます。

Q2:その通りです。「たとえば、あるスレッドがコレクションを反復処理しているときに、あるスレッドがコレクションを変更することは一般に許可されていません。一般に、反復の結果はこれらの状況では未定義です。一部のIterator実装(すべての汎用コレクションの実装を含む) JREによって提供される実装)は、この動作が検出された場合にこの例外をスローすることを選択できます。これを行うイテレータは、不確定な時間に任意の非決定的な動作のリスクを冒すのではなく、迅速かつクリーンに失敗するため、フェイルファストイテレータと呼ばれます。将来。" -java doc http://docs.oracle.com/javase/1.5.0/docs/api/java/util/ConcurrentModificationException.html

Q3:使用するリストをロックするには

Collections.unmodifiableList(list);

これはすべてのコレクションで機能し、ユーザーがデータを変更することを禁止します。つまり、ユーザーに「読み取り専用」のコピーを提供します。コレクションクラスの詳細については、こちらをご覧ください。http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html

于 2012-11-10T18:17:38.797 に答える
1

質問番号3について: リストをロックする方法は2つあります

1)暗黙的なモニターロック:コレクションのファクトリメソッドを使用して同期リストを作成する場合は、ラッパーオブジェクトを使用してロックを作成できます。

    List<T> list = new ArrayList<T>();
    List<T> slist = Collections.synchronizedList(list);
    synchoronized(slist) {
    //code
    } 

この場合、slistは、反復および複合アクション中のロックに使用されます。

2)オブジェクトクラスをロックとして使用できます

    Object lock = new Object();
    synchronized (lock) {
       // ...
     }
于 2012-11-10T18:33:08.967 に答える