2009-05-22 15 views
5

私は通常、タイトルに記載されているインターフェイスの具象クラスを使用するだけで十分です。通常、他のタイプ(LinkedListやTreeSetなど)を使用する場合、その理由は機能性であり、パフォーマンスではありません(たとえば、キュ​​ーのLinkedListなど)。Java:リスト用のArrayList、Map用のHashMap、Set用のHashSet?

私は時々デフォルトの10以上の初期capcacityと16のデフォルトのバケット以上のHashMapでArrayListを構築しますが、私は通常(特にビジネスCRUDの場合)自分自身が決して "hmmm ... should"私は、リスト全体を挿入して反復しようとしているのであれば、ArrayListの代わりにLinkedListを使用しますか?

ここで他の人たちが何を(そしてなぜ)使うのか、どんなタイプのアプリケーションを開発しているのだろうと思っています。

答えて

10

これは間違いなく私のデフォルトですが、多くの場合、リストの大半がArrays.asListを経由して配列に変換されるようになっています。

しかし、一貫性のあるメンテナンス可能なコードを維持するという観点からは、誰かがコードを読んで代替案を見たときに、そのコードを標準化して、 。

私はサブタイプを参照する特別な理由がない限り、常にパラメータ、変数をCollection、Map、Listとして入力します。必要なときに切り替えるのは1行です。

ランダムアクセスが必要な場合は明示的にArrayListを必要とすることがありますが、実際には実際には起こりません。

+3

繰り返しを繰り返しても、メモリオーバーヘッドが少ないため、通常はArrayListが優れています。 –

+2

あなたは正当な理由がない限り、常にインターフェイスクラスを常に使用しています。ArrayListを利用したListを使った実装をCopyOnWriteArrayListに変換することで、現実世界の問題を解決しました。 1行の修正。常にインターフェイスを使用してください。 – basszero

+0

@マイケル、良い点が、私の文章では、特定の番号の要素を取得するよりも、リストに追加し、そのサイズを知っていることが一般的であることに文句を言わなかった。しかし、私はまだデフォルトでArrayListを使用しています。 – Yishai

1

データ構造のパフォーマンスに関するクラスからちょうど出てきたので、実装を選択する前に、私が開発しているアルゴリズムの種類や構造の目的を調べます。

たとえば、ランダムアクセスが多いリストを作成する場合、ランダムアクセスのパフォーマンスが良いのでArrayListを使用しますが、リストに多くのものを挿入すると代わりにLinkedListを選択するかもしれません。 (私は現代的な実装で多くのパフォーマンス障壁が取り除かれていることは分かっていますが、これが最初の例です)。sorting algorithmsを扱っているデータ構造については、Wikipediaのページを参照してください。パフォーマンスは特に重要です)、およびデータ構造上のさまざまな機能のパフォーマンスの測定に関する一般的な説明については、Big O notationに関する記事を参照してください。

2

ええ、私はそれらをデフォルトとして使用します。私は一般的に、他のクラス(通常)は特定の具体的なクラスが何であるかを知る必要がないので、パブリッククラスのメソッドでは、常にインターフェイスの型(Map、Set、Listなど)を返すというルールを持っています。クラスのメソッドの中で、具体的な型は、余分なメソッドにアクセスする必要がある場合にのみ使用します(またはコードの理解を容易にする場合)。そうでない場合は、インターフェイスが使用されます。

具体的なクラスの可視性に依存するので、時間が経つにつれて変わる可能性があるので(特にコードが複雑になるほど)、使用するルールにはかなり柔軟性があります。

0

私はキューに*キュークラスの1つを使用する傾向があります。ただし、スレッドセーフティが必要ない場合は、LinkedListを使用することをお勧めします。

3

リスナー)ArrayListの代わりにCopyOnWriteArrayListを使用すると意味があります。ほとんどの場合、基本的な実装は十分です。

+0

CopyOnWriteArrayListを使用する唯一の理由は、スレッドセーフな実装(ブロッキングなし) ArrayListとCopyOnWriteArrayListの間に違いはありません。 –

0

実装タイプ(ArrayList, HashMap)の代わりにインターフェイスタイプ(List, Map)を使用すると、メソッド内では無関係です。パブリックAPI、つまりメソッドシグネチャなどでは主に重要です(「public」は必ず「外部あなたのチーム)

メソッドがArrayListをパラメータとしていて、何か他のものがある場合は、あなたはデータを無意識にコピーする必要があります。パラメータタイプがListの場合、呼び出し元は例えば、Collections.EMPTY_LISTまたはCollections.singletonList()を使用してください。

2

実際、alwayそれらの実装ではなく、基本インタフェースCollection、List、Mapを使用します。思考をさらに柔軟にするために、静的なファクトリメソッドの背後に実装を隠すことができます。これにより、より良いものを見つけた場合に備えて別の実装に切り替えることができます(このフィールドに大きな変更があるとは思えません。もう一つの利点は、構文がジェネリックのおかげで短くなるということです。

Map<String, LongObjectClasName> map = CollectionUtils.newMap(); 

instead of 

Map<String, LongObjectClasName> map = new HashMap<String, LongObjectClasName>(); 


public class CollectionUtils { 
..... 

public <T> List<T> newList() { 
     return new ArrayList<T>(); 
    } 

    public <T> List<T> newList(int initialCapacity) { 
     return new ArrayList<T>(initialCapacity); 
    } 

    public <T> List<T> newSynchronizedList() { 
     return new Vector<T>(); 
    } 

    public <T> List<T> newConcurrentList() { 
     return new CopyOnWriteArrayList<T>(); 
    } 

    public <T> List<T> newSynchronizedList(int initialCapacity) { 
     return new Vector<T>(initialCapacity); 
    } 

... 
} 
+0

ええ、私はこのようなことをすることを考えました。私は一人ではないことを知ってうれしい! – GreenieMeanie

1

質問に記載されている実装を頻繁に使用するとは思いますが、実際には「デフォルト」はありません。私が取り組んでいる問題が何であれ、何が適切なのかを考えて、それを使う。私はちょうど盲目的にArrayListを使用するようにデフォルトしていません、私は "よく、私はこのリストの真ん中で要素を反復して取り除くことをたくさんするつもりですので、私は30秒の思考を入れました。 LinkedList "。

そして、私はほとんどの場合、実装ではなく参照用にインターフェイスタイプを使用します。 ListLinkedListが実装する唯一のインターフェイスではないことに注意してください。プログラマだった何を意味するとき

LinkedList<Item> queue = new LinkedList<Item>(); 

:私はこの多くを見る

Queue<Item> queue = new LinkedList<Item>(); 

私もIterableは、かなりの量のインターフェースを使用します。

1

キューにLinkedListを使用している場合は、代わりにDequeインターフェイスとArrayDeque実装クラス(Java 6で導入)を使用することを検討してください。 ArrayDequeのJavadocを引用するには、次のスタックとして使用され、キューとして使用した場合のLinkedListより 速いとき

このクラスは スタックよりも高速である可能性が高いです。

0

私はあまりにも通常、ArrayListを使用しますが、状況によってはTreeSetまたはHashSetを使用します。しかし、テストを書くときには、Arrays.asListとCollections.singletonListもよく使われます。私は主にスレッドローカルコードを書いていますが、さまざまな並行クラスも使用することができます。

また、私が本当に欲しいのは、LinkedHashSet(利用可能になる前)だったときにArrayListを使用したことがありました。

+0

私はイテレータを挿入順に返す前にLinkedHashSetを使用していました。 – GreenieMeanie

関連する問題