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对象可见......但对该对象的“更改”操作将不起作用。

(另一种方法是创建原始Vector对象的副本,但我很确定这不符合您的要求。)


1 - 请注意,readOnly对象是 aList但不是 a Vector。这应该不是问题,除非您错误地将 getter 声明为返回 a Vector。如果您已经这样做了,并且无法纠正错误,那么您将需要按照VectorEvgeniy Dorofeev 的答案创建自己的子类。否则Collections.unmodifiableList(...)会做得很好。

于 2012-12-19T06:06:09.953 回答
2

使其成为private您的类的成员,并且仅提供返回向量的不可变版本的 getter,作为public访问它的一种方式,使用您提到的函数 ( Collections.unmodifiableList())。

于 2012-12-19T05:12:53.960 回答
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 回答
1

试试这个:

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

使 vector 成为您班级的私人成员。向调用者公开一个公共方法,该方法将获得对 unmodifiableCollection 的引用。

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

为了在您的内部类中使用,您可以直接引用向量或创建一个private方法来返回对集合的引用。

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

我想如果你把你的Vectoras privatemember 属性放在你的write methodsasprivate中,read methods那么public你就可以,例如

    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

在我看来,通过将向量实例设为私有并将 setter 设为私有而将 getter 设为公开将是正确的路径。为了 :

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

它只会读取实例,但是,它仍然允许访问其他类来调用 add/set/remove 方法,但调用这些方法会导致引发 UnsupportedException。

此外,根据您的要求,您正在寻找矢量的更新/在其中添加新元素。因此,可以通过寻找并发包以使其更安全。

于 2012-12-19T05:38:01.677 回答
0

最好提供 Vector 的副本,而不是提供 Vector 的原始参考,如下所示:

Vector vector = // your vector object in your class 
public Vector<String> getMyVercorObject(){
     return (Vector<String>)vector.clone() ;
}
于 2012-12-19T05:43:19.377 回答
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 回答