4

プログラムでデータを管理する必要があります。Java-Vector は同期されているため目的に適しており、インデックスを介して動的サイズと高速ランダム アクセスを提供します。

しかし、他のプログラム クラスに対してはベクターを読み取り専用にし、自分のクラスに対しては読み取り/書き込みを行いたいと考えています。

について読みましCollections.unmodifiableList()たが、Vector変更不可にすると、クラスに対しても読み取り専用になります。

どうすればこの問題を解決できますか?

4

9 に答える 9

5

について読みましCollections.unmodifiableList()たが、Vector を変更不可にすると、クラスに対しても読み取り専用になります。

そのメソッドが何をするかを誤解していると思います。実際には、既存のリストに対して変更不可能なラッパーを作成し、元のリストを変更可能なままにします。

したがって、要件を処理する方法は、次のようにすることです1

private Vector<?> myVector = new Vector<?>();
private List<?> readOnly = Collections.Collections.unmodifiableList((myVector);

public List<?> getList() { return readOnly; }

アクセスできるものはすべて、myVectorそこから要素を追加および削除できます。変更はオブジェクトを介して表示readonlyされますが、そのオブジェクトに対する「変更」操作は機能しません。

(もう 1 つのアプローチは、元のVectorオブジェクトのコピーを作成することですが、それでは要件を満たさないと確信しています。)


1 -readOnlyオブジェクトは ではあるListが ではないことに注意してくださいVector。ゲッターをVector. それを行っても間違いを修正できない場合は、VectorEvgeniy Dorofeev の回答に沿って独自のサブクラスを作成する必要があります。そうでなければCollections.unmodifiableList(...)うまくいきます。

于 2012-12-19T06:06:09.953 に答える
2

変更不可能なベクター (リストだけでなく) が本当に必要な場合は、メソッドを次のように作成します。

public static Vector unmodifiableVector(Vector v) {
    return new Vector(v) {
        @Override
        public void add(int index, Object element) {
            throw new UnsupportedOperationException();
        }

        @Override
        public synchronized boolean addAll(Collection c) {

        @Override
        public synchronized void addElement(Object obj) {

        // ... other mutators
    }
}
于 2012-12-19T06:08:16.007 に答える
2

それをあなたのクラスのメンバーにし、あなたが言及した関数を使用して、それにアクセスprivateする方法としてベクトルの不変バージョンを返すゲッターのみを提供します( )。publicCollections.unmodifiableList()

于 2012-12-19T05:12:53.960 に答える
1

これを試して:

Collections.unmodifiableList(myList);
于 2012-12-19T05:16:50.310 に答える
0

ベクターインスタンスをプライベートにし、セッターをプライベートとしてゲッターをパブリックとして提供することは、私の意見では正しいパスです。のために :

List<T> readOnlyList = Collections.unmodifiableList(myList);

インスタンスは readnoly になりますが、他のクラスへのアクセスで add/set/remove メソッドを呼び出すことは引き続き可能ですが、これらのメソッドを呼び出すと UnsupportedException が発生します。

また、要件に基づいて、ベクターの更新/新しい要素の追加を探しています。そのため、並行パッケージを探して、より安全にすることができます。

于 2012-12-19T05:38:01.677 に答える
0

最善の方法は、Vector内部的に使用し、メソッドを使用してミューテーション (追加、削除など) のみを公開し、インターフェイス ( List) を使用して変更不可能なビューのみを返すことです。このような実装は次のようになります (たとえば、要素が文字列であるとしましょう)。

private final List<String> list = new Vector<String>();

/** Adds the specified element. */
public void addElement(String element) {
    list.add(element);
}

/** Replaces all elements. */
public void setElements(List<String> newElements) {
    list.clear();
    list.addAll(newElements);
}

/** Returns all elements. */
public List<String> getElement() {
    return Collections.unmodifiableList(list);
}

このようにして、クラスはリストに完全にアクセスできますが、外部エンティティはパブリック メソッドを使用してのみ変更できます。

Vectorほとんど使用されていないことに注意してください。スレッド セーフ リストが必要な場合は、以下ArrayListと組み合わせて検討してsynchronizedListください。

private final List<String> list = Collections.synchronizedList(new ArrayList<String>());
于 2012-12-19T06:01:34.013 に答える
0

ベクトルをクラスのプライベート メンバーにします。unmodifiableCollection への参照を取得するパブリック メソッドを呼び出し元に公開します。

public Vector getVector(){
     return Collections.unmodifiableList(yourVector) ;
}

内部クラスで使用するために、ベクトルを直接参照するか、privateコレクションへの参照を返すメソッドを作成できます。

private Vector getMyVector(){
         return yourVector ;
    }
于 2012-12-19T05:12:54.777 に答える
0

Vectorasメンバー属性を all as while asとprivate一緒に作成すれば、問題ないと思いますwrite methodsprivateread methodspublic

    private Vector<T> myVector = ...

    private void setMyVector(Vector<T> vector){
        myVector = vector;
    }

    private void addElement(T element){
        myVector.add(element);
    }

    public T getElement(int indx){
        return myVector.get(indx);
    }
    ....
    ....
于 2012-12-19T05:13:55.650 に答える
0

次のように、ベクターの元の参照を提供するのではなく、ベクターのコピーを提供することをお勧めします。

Vector vector = // your vector object in your class 
public Vector<String> getMyVercorObject(){
     return (Vector<String>)vector.clone() ;
}
于 2012-12-19T05:43:19.377 に答える