私はよくArrayList
「通常」の代わりに使用しarray[]
ます。
を使用すると、浮気をしている(または怠惰になっている)ように感じますが、オーバーアレイArrayList
を使用しても大丈夫ですか?ArrayList
配列は強く型付けされており、パラメーターとして適切に機能します。コレクションの長さがわかっていて、それが固定されている場合は、配列を使用する必要があります。
ArrayListsは強く型付けされていません。すべての挿入または再試行では、元の型に戻すためにキャストが必要になります。特定の型のリストを取得するメソッドが必要な場合、任意の型を含むArrayListを渡すことができるため、ArrayListは不十分です。ArrayListsは内部で動的に拡張する配列を使用するため、容量に達したときに内部配列のサイズを拡張するヒットもあります。
本当に使いたいのは、のような一般的なリストですList<T>
。これには、ArrayとArrayListsのすべての利点があります。強く型付けされており、可変長のアイテムをサポートします。
Bob と Frederick の回答に加えて、配列には共分散がありますが、ジェネリック リストにはないことを指摘したいと思います。たとえば、 型の配列はMyChildClass[]
に簡単にキャストできますがMyParentClass[]
、少なくとも直接的にはList<MyChildClass>
にキャストできません。List<MyParentClass>
共分散が必要な場合は、配列を使用するか、LINQ の Cast() メソッドまたはその他の手段を使用して各項目を個別にキャストするか、C# 4 を待ちます。
ここでもう 1 つ考えられるのは突然変異です。配列 ( T[]
) は完全に可変であり、保護できません。List<T>
有用な拡張ポイントは提供しませんが、Collection<T>
(または他の多くのIList<T>
実装) のようなものを使用すると、コードを追加できます。たとえば、アイテムを追加する前にチェックすることができます。同様に、読み取り専用の実装を使用できますIList<T>
。これは、不変性が望ましいスレッド セーフに役立ちます。
params
私は配列を内部メソッド ロジックで (おそらくローカル変数として)引数として使用するか、アイテムの長さがわかっている高度に最適化されたいくつかのケースで使用する傾向があり、コードがそれを変更しないことを選択することを知っています (変数として)。プライベート フィールド)。それ以外は、List<T>
アイテムの追加/削除時のオーバーヘッドがはるかに少ないため、より一般的です。
コードのその部分が絶対的にパフォーマンスクリティカルでない限り、ArrayListの使用は完全に問題ありません。
さらに良いことArrayList
に、 を使用する場所では、List<T>
代わりにジェネリック コレクションを使用してください。前者よりも強く型付けされています。
Fabulous Adventures In Codingは、 Arrays がやや有害と見なす記事を書きました。とても興味深い読み物です。
私はJavaの観点からこれに答えていますが、それは同じ基本的な問題です. より高度な抽象化を使用することに罪悪感を感じるべきではありません。結局のところ、あなたはString
の代わりに s を使用しchar[]
ていbyte[]
ます。List
さらに一歩進んで、可能な場合はインターフェイスを使用することをお勧めします。1 段階下げる唯一の理由は、パフォーマンス上の理由です。
より高いコレクションの抽象化を使用すると、多くの利点があります。デコレーターを追加して、リストを読み取り専用にしたり、固定サイズにしたり、コレクションに出入りする項目をチェックしたり、ビューを使用したりできます ( GetRange
C# およびsubList
Java を参照)。
ちなみに、ArrayList
は常にプリミティブ配列に基づいている必要があります。そうでない場合、名前が間違っています。操作は通常、プリミティブ配列を使用するときに期待される方法で実装されます。リンクされたリストが使用される場合、通常は -- という名前が付けられLinkedList
ます。これは、インターフェイスを使用する利点でもあります。後で使用する実装について考えを変えることができます。
コレクションの使用を不格好にするいくつかのことがあります。1 つの注意点は、コレクションは通常オブジェクトに基づいており、言語ではプリミティブ型とオブジェクト型の間にかなりのギャップがあることです。限られたジェネリックもあまり役に立ちません。それでも、特に理由がない限り、配列よりもコレクションをお勧めします。
プリミティブ値については、GNU Troveなどのプリミティブ コレクション ライブラリの使用を検討することもできます。ただし、C# に似たものがあるかどうかはわかりません。
プリミティブ型の配列が必要な場合は、自動ボックス化とボックス化解除を回避するため、パフォーマンスを向上させるために配列を使用します。ただし、事前に必要なサイズがわかっている場合に限ります。
たとえば、特定の型のみを処理する場合は、ArrayList を使用しないでください。たとえば、バイト配列のみが必要な場合は、バイト配列のみを受け入れる必要があります。
List の代わりに ArrayList を使用することさえ考えられると思います。
配列のサイズは静的であるため、設計時にサイズがわかっている場合は、配列を使用してください。より高速に動作するはずですが、自分でテストしていません。オブジェクトの数を頻繁に変更する必要がある場合 (コレクションからオブジェクトを追加または削除する場合) は、ArrayList を使用するか、.NET 2 の一般的な List を使用することをお勧めします。これは使いやすいので、パフォーマンスが重要でない場合は、いつでも List を使用できます。