Javaでサイズ変更可能な配列を実行する最良の方法は何ですか? Vector を使用してみましたが、挿入を行うときにすべての要素がシフトされます。また、要素はそのままの状態で拡張できる配列が必要です。これには簡単な答えがあると確信していますが、まだよくわかりません。
9 に答える
代わりに、 ArrayListを使用できます。これは、List インターフェイスのサイズ変更可能な配列の実装です。
使用法 (文字列を使用):
List<String> myList = new ArrayList<String>();
myList.add("a");
myList.add("c");
myList.add("b");
順番は、a、c、b のように入力します。
次のような個別のアイテムを取得することもできます。
String myString = myList.get(0);
これにより、0番目の要素「a」が得られます。
三条が指摘したように: " An array is a static datastructure, so they can't grow
". リスト インターフェイスは、配列によってバックアップできます(たとえば、Kevin が投稿で指摘したようなArrayListなど)。リスト構造がいっぱいで、新しいアイテムをリストに追加する必要がある場合。次に、構造体は最初に、古い要素とリストに追加する必要がある新しい要素を含むことができる新しい配列を作成します。
リスト インターフェイスにはさまざまな実装があり、すべてに長所と短所があり、問題セットを解決するのに最適なものを選択する必要があります。以下に、どの実装をいつ使用するかを簡単にまとめます。
スレッドセーフでない実装:
- ArrayList : List インターフェイスのサイズ変更可能な配列の実装。
size, isEmpty, get, set, iterator, and listIterator
一定時間内に多くの操作を実行する場合は、この実装を使用する必要があります。操作は償却された定数時間で実行されます。add
つまり、n 個の要素を追加するには O(n) 時間かかります。get()
さらに lookups( ) を実行してから list( ) に項目を追加する場合は、この実装を使用する必要があると思いますadd()
。 - LinkedList : この実装は配列によるバックアップではなく、ノードを「リンク」します。
add()
私の意見では、それ以上のことをしている場合は、この実装を使用する必要がありますget()
。
スレッドセーフな実装:
これらのリストの実装はスレッドセーフではないことに注意してください。つまり、複数のスレッドからアクセスすると競合状態になる可能性があります。複数のスレッドから List 実装を使用する場合は、java.util.concurrentパッケージを調べて、そのクラスの実装を使用することをお勧めします。
他の回答で説明されている理由により、おそらく Vector の代わりに ArrayList を使用する必要があります。
でも ...
Vector を使用してみましたが、挿入を行うと、すべての要素がシフトされ、要素がそのまま残る配列が必要になります。
を実行すると、要素のシフトinsertElementAt(pos, elem)
が具体的に要求されます。要素をシフトしたくない場合は、set(pos, elem)
代わりに使用する必要があります。または、ベクトルの最後に要素を追加する場合は、 も使用できますadd(elem)
。
ちなみに、前の段落はList
だけVector
でなく、 のすべての実装に適用されますが、実装の詳細とパフォーマンスは の種類によって異なりますList
。
Vectorを使用してみましたが、挿入を行うとすべての要素がシフトします。拡張できる配列が必要ですが、要素はそのまま残ります。
Vectorの代わりにArrayListを使用することをお勧めします。
これらは両方ともほぼ同じインターフェースを提供し、を呼び出すことで要素を両方に置き換えることができますset(idx, element)
。それは何の変化もしません。ただし、配列を拡張することもできません。すでに占有されている位置(配列の現在のサイズを超えない)にのみ挿入でき、最後に使用する必要がある新しい要素を追加できますadd(element)
。
ArrayListとVectorの違いは、Vectorにはおそらく不要な同期コードがあるため、ArrayListが少し高速になることです。
ArrayList と LinkedList
スペースの複雑さ:
a)ArrayList:要素を動的に追加するたびに、初期化時にメモリのチャンクを割り当て、最大サイズに達するたびに倍増します。
b) LinkedList: リストにアイテムを追加するたびにのみメモリを割り当てます。
ランタイムの複雑さ:
a) ArrayList: リンクされたリストと比較して、検索は高速で、挿入と削除は低速です
b) LinkedList: 配列リストに比べて挿入と削除が高速で、検索が遅い
すべての要素が既に挿入または削除された後に配列データを操作したい場合は、LinkedList または ArrayList を作成しようとする方法があり、単純にサイズを変更し、データの入力が完了したら、ArrayList を Array に転送してから、配列に対して通常行うすべてのことを行います。
ArrayList または LinkedList を使用します。
コレクションフレームワークですばらしいクラスを使用することは、配列を使用するよりも優れています。しかし、あなたの質問が「クイズ」の観点からのものである場合、これがあなたがすべきことです。次のような独自のサイズ変更方法を作成します。
int[] oldArray = {1,2,3};
int oldSize = java.lang.reflect.Array.getLength(oldArray);
Class elementType = oldArray.getClass().getComponentType();
Object newArray = java.lang.reflect.Array.newInstance(
elementType,newSize);
int preserveLength = Math.min(oldSize,newSize);
if (preserveLength > 0)
System.arraycopy (oldArray,0,newArray,0,preserveLength);
oldArray = newArray;