CodeGym /Java Blog /ランダム /Java ベクトル
John Squirrels
レベル 41
San Francisco

Java ベクトル

ランダム グループに公開済み
おそらく、Java の配列にすでに出会ったことがあるでしょうし、その主な欠点の 1 つがサイズの一定性であることをご存知でしょう。特定のサイズの配列を作成した後は、それを変更することはできません。Java 言語には、この問題を解決する Java コレクション フレームワーク クラスがいくつかあります。その 1 つは Java Vectorクラスです。この記事で説明します。

ベクタークラスとは

まえがきで書いたように、 Java Collection Framework のVectorクラスを使用すると、配列の静的サイズの問題が解消されます。Java Vector は動的配列の一種であり、サイズが拡大または縮小する可能性があります。Vectorコレクション クラスを使用すると、要素のグループを単純なオブジェクトとして保存し、さまざまなメソッドを通じてそれらを操作できます。Vector クラスはjava.utilパッケージから入手できます。したがって、Java の Vector は、配列のサイズが事前にわからない場合、またはプログラムの存続期間中に次元を変更できる「配列」が必要な場合に使用できます。ベクトルは次のことをすぐに言わなければなりません。このクラスはすでにかなり古いものですが、その後、ほとんどの場合にそれを置き換えることができるコレクションが登場しました。Java Vector の一般的な「類似物」はArrayListクラスです。これらのクラス間の最も重要な違いは、Vector は同期されるのに対し、ArrayList は同期されないことです。これら 2 つのクラスと、 Vectorクラスの最新の類似物とのその他の違いについては、「Vector クラスの問題点」セクションで少し後ほど説明します。

Java ベクトル メソッド

Javaベクターメソッドは次のとおりです。
  • void add(int index, Object element) は、指定された要素をベクトルの指定された位置に挿入します。

  • boolean add(Object o) は、指定された要素をベクトルの末尾に追加します。

  • boolean addAll(Collection c) は、指定されたコレクション内のすべての要素を、指定されたコレクション反復子によって返される順序でベクトルの末尾に追加します。

  • boolean addAll(int index, Collection c) は、指定された Collection 内のすべての要素をベクトルの指定された位置に挿入します。

  • void addElement(Object obj) は、指定されたコンポーネントをこのベクトルの末尾に追加し、そのサイズを 1 つ増やします。

  • int Capacity() は、このベクトルの現在の容量を返します。

  • void clear() は、このベクトルからすべての要素を削除します。

  • Object clone() は、このベクターのクローンを返します。

  • boolean contains(Object elem) は、指定されたオブジェクトがこのベクトルのコンポーネントであるかどうかをテストします。

  • boolean containsAll(Collection c) は、ベクトルに指定されたコレクションのすべての要素が含まれている場合に true を返します。

  • void copyInto(Object[] anArray) は、このベクトルのコンポーネントを指定された配列にコピーします。

  • Object elementAt(int index) は、指定されたインデックスにあるコンポーネントを返します。

  • Enumeration elements() は、このベクトルのコンポーネントの列挙を返します。

  • void ensureCapacity(int minCapacity) は、必要に応じてこのベクトルの容量を増やし、少なくとも最小容量引数で指定された数のコンポーネントを保持できるようにします。

  • booleanquals(Object o) は、指定されたオブジェクトをこのベクトルと比較します。

  • オブジェクト firstElement() は、このベクトルの最初のコンポーネント (インデックス 0 の要素) を返します。

  • Object get(int index) は、このベクトル内の指定された位置にある要素を返します。

  • int hashCode() は、このベクトルのハッシュ コード値を返します。

  • int IndexOf(Object elem) は、指定された引数の最初の出現を検索し、equals メソッドを使用して等しいかどうかをテストします。

  • intindexOf(Objectelem,intindex) は、指定された引数の最初の出現を検索し、index から開始し、equals メソッドを使用して等しいかどうかをテストします。

  • void insertElementAt(Object obj, int Index) は、指定されたオブジェクトをコンポーネントとしてこのベクトルの指定されたインデックスに挿入します。

  • boolean isEmpty() は、このベクトルに欠落しているコンポーネントがないかテストします。

  • オブジェクト lastElement() は、ベクトルの最後のコンポーネントを返します。

  • int lastIndexOf(Object elem) は、このベクトル内で指定されたオブジェクトが最後に出現したインデックスを返します。

  • int lastIndexOf(Object elem, int Index) は、指定されたインデックスから開始して、指定されたオブジェクトを逆方向に検索し、そのインデックスを返します。

  • Object Remove(int Index) は、このベクトル内の指定された位置にある要素を削除します。

  • boolean replace(Object o) は、このベクトル内で最初に出現した指定された要素を削除します。ベクトルに要素が含まれていない場合、ベクトルは変化しません。

  • boolean RemoveAll(Collection c) は、指定された Collection に含まれるベクトルからすべての要素を削除します。

  • void RemoveAllElements() は、ベクトルからすべてのコンポーネントを削除し、そのサイズをゼロに設定します。

  • boolean replaceElement(Object obj) は、このベクトルから引数の最初 (最も低いインデックス) の出現を削除します。

  • void RemoveElementAt(int index) は、インデックスの要素を削除します。

  • protected void RemoveRange(int fromIndex, int toIndex) は、インデックスが fromIndex (両端を含む) と toIndex (両端を含む) の間にあるすべての要素をこの List から削除します。

  • boolean restartAll(Collection c) は、指定されたコレクションに含まれるベクトルの要素のみを保持します。

  • Object set(intindex, Object element) は、このベクトル内の指定された位置にある要素を指定された要素に置き換えます。

  • void setElementAt(Object obj, int Index) は、このベクトルの指定されたインデックスにあるコンポーネントを指定されたオブジェクトとして設定します。

  • void setSize(int newSize) は、このベクトルのサイズを設定します。

  • int size() は、このベクトル内のコンポーネントの数を返します。

  • List subList(int fromIndex, int toIndex) は、この List の fromIndex と toIndex の間の部分の表現 (ビュー) を返します。

  • Object[] toArray() は、このベクトルのすべての要素を正しい順序で含む配列を返します。

  • Object[] toArray(Object[] a) は、このベクトルのすべての要素を正しい順序で含む配列を返します。返される配列の実行タイプは、指定された配列のタイプです。

  • String toString() は、各要素の文字列表現を含むこのベクトルの文字列表現を返します。

  • voidrimToSize() は、このベクトルの容量をベクトルの現在のサイズにトリミングします。

Java ベクトルの例


import java.util.Vector;

public class VectorExample {

   public static void main(String[] args) {
       Vector vector = new Vector();
       System.out.println("the size of the empty vector = " +  vector.size());
       //adding some vector elements
       vector.add("Johnny");
       vector.add("Ivy");
       vector.add("Ricky");
       System.out.println(vector); 
       
       //adding more vector elements       
       vector.add("Johnny");
       vector.add("Paul");
       System.out.println(vector);
       System.out.println("the size of the vector = " +  vector.size());
       System.out.println("the first element of the vector = " + vector.firstElement());

       //here the program will print out the first appearance of "Johnny" element
       System.out.println(vector.indexOf("Johnny"));
       //program will print out the first appearance of "Johnny" element starting from the element 1
       System.out.println(vector.indexOf("Johnny", 1));
       vector.clear(); //deleting all vector elements
       System.out.println("the size of the vector after clear method = " +  vector.size());

   }
}
このプログラムの出力は以下のとおりです。
空のベクトルのサイズ = 0 [Johnny, Ivy, Ricky] [Johnny, Ivy, Ricky, Johnny, Paul] ベクトルのサイズ = 5 ベクトルの最初の要素 = Johnny 0 3 クリア後のベクトルのサイズメソッド = 0

Vectorクラスの何が問題なのでしょうか?

Java Vectorクラスのドキュメントによると、プログラムにスレッドセーフな実装が必要ない場合は、Vectorの代わりにArrayListを使用することをお勧めします(コレクション フレームワークのより効果的な参加者)。Vectorの代わりにArrayListクラスを使用して、上の例を少し変更してみましょう。

import java.util.ArrayList;
import java.util.List;

public class ArrayListExample {

       public static void main(String[] args) {
           List vector = new ArrayList();
           //Vector vector = new Vector();
           System.out.println("the size of the empty vector = " +  vector.size());
           vector.add("Johnny");
           vector.add("Ivy");
           vector.add("Ricky");
           System.out.println(vector);
           vector.add("Johnny");
           vector.add("Paul");
           System.out.println(vector);
           System.out.println("the size of the vector = " +  vector.size());
           //System.out.println("the first element of the vector = " + vector.firstElement());

           //here the program will print out the first appearance of "Johnny" element
           System.out.println(vector.indexOf("Johnny"));
           //program will print out the first appearance of "Johnny" element starting from the element 1
           //System.out.println(vector.indexOf("Johnny", 1));
           vector.clear();
           System.out.println("the size of the vector after clear method = " +  vector.size());

       }
   }
ArrayListクラスのこのバリエーションにはそのようなメソッドがないため、Vector.indexOf("Johnny", 1) を含む行をコメント アウトしました。同じ理由で、vector.firstElement()行はコメントアウトされました。他のすべての点では、プログラムは最初の結果と同じ結果を生成します。もちろん、このような例では、ArrayList がVectorよりも優れている理由は明らかではありません。これには、たとえばスレッドに関するより多くの知識が必要です。ここではその理由を列挙します。まず、Vectorクラスは同期されていますが、奇妙に思われますが、完全にスレッドセーフであるとは言えません。実際のところ、Vector はVector全体ではなく、各操作を同期します。インスタンス自体。これは、個々の操作ではなく一連の操作全体を同期する必要があるプログラムで問題になる可能性があります。たとえば、あるスレッドがベクターを反復処理し、別のスレッドがベクターのインスタンスを構造的に変更している場合、反復子は ConcurrentModificationException をスローします。2 つのスレッドが異なる操作を実行する場合、同時にVectorインスタンスを操作できることがわかりました。第二に、ベクトルこのクラスのオブジェクトにはサイズ変更可能な配列と同期があるため、最高のパフォーマンスが得られません。この組み合わせは、同期が必要かどうかに関係なく、操作をブロックするための追加のオーバーヘッドを意味します。確かに、これはパフォーマンスに影響します。さらに、各操作でベクトルを同期すると、操作ごとに何度もロックを取得することになるため、パフォーマンスに悪影響を及ぼします。クラスのインスタンス全体が同期されている場合は、ロックも 1 回取得されるため、はるかに効率的になります。第三に、Vector はいくつかの従来のメソッドをサポートしています。たとえば、Elements()。このメソッドは、ベクトルのコンポーネントの列挙を返します。プログラマーは、多くの理由から列挙に Iterator または ListIterator を使用することが最も多いです。特に、Enumeration には、remove()メソッドが定義されていません。これは、反復中にリストの構造を変更できないことを意味します。また、ListIterator とは異なり、Enumeration は双方向アクセスを提供しません。ご覧のとおり、Vector にはかなり多くの問題があります。List インターフェイスのスレッドセーフな実装がまだ必要な場合はどうすればよいでしょうか? この場合、ArrayList は役に立ちませんが、たとえばVectorの代わりにCopyOnWriteArrayListクラスを使用できます。ArrayListのスレッドセーフなバリアントとして位置付けられます。。Collections synchronizedList()メソッドを使用してArrayListを同期することもできます。

Vector には実際にいくつかの問題があります...なぜ Java にまだ存在し、なぜそれを教える必要があるのでしょうか?

そもそもなぜVectorクラスを研究するのでしょうか?という疑問が生じます。そしてなぜまだ Java から削除されていないのでしょうか? 実際のところ、Java は下位互換性の原則を謳っています。これは、何年も前に書かれた古いコードはすべて、最新バージョンの Java で理解できることを意味します。さらに、Java 環境には、何十年にもわたってサポートされているエンタープライズ レベルのアプリケーションが数多くあります。仕事の中でこのような「恐竜」に対処しなければならない可能性は十分にあるため、非効率なレガシー クラスを含むコードなどの予期せぬ事態に備えておく必要があります。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION