2012-12-19 27 views
4

我需要在我的程序中管理数据,其中Java-Vector适合于同步的目的,通过索引提供动态大小和快速随机访问。Java中的不可修改向量

但我想让我的矢量只读其他程序类和读写我自己的类。

我读了约Collections.unmodifiableList(),但如果我让我的Vector不可修改,它也将变成只读给我的班级。

我该如何解决这个问题?

回答

4

我读到Collections.unmodifiableList(),但如果我让我的矢量不可修改,它将成为只读到我的类为好。

我想你误解了那种方法。实际上,它为现有列表创建了一个不可修改的包装,使原始列表可修改。

因此处理您的要求的办法是做这样的事情:有权访问myVector仍然可以添加和删除其元素

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

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

什么。通过readonly对象可以看到更改...但对该对象的“更改”操作不起作用。

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


1 - 请注意,readOnly对象是List但不是Vector。这不应该是一个问题,除非你犯了一个错误,宣布获得者返回Vector。如果你已经这样做了,而且你不能纠正这个错误,那么你需要沿着Evgeniy Dorofeev的答案创建你自己的子类Vector。否则Collections.unmodifiableList(...)将会很好。

+0

感谢这种方法适合我 – Nargis

2

使其成为您的类的private成员,并且只使用您提到的函数(Collections.unmodifiableList())提供将get方法的不可变版本作为public返回的访问方式。

0

使向量成为您班级的私人会员。向调用者公开一个公共方法,该方法将获得对不可修改的Collection的引用。

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

对于内部类的使用,您可以直接引用的载体或创建一个private方法,将参考返回集合。

private Vector getMyVector(){ 
     return yourVector ; 
    } 
+1

你会得到一个铸件类异常 –

0

我认为,如果你与所有write methods作为privateread methodspublic,你会沿着使您Vector作为private成员属性,在OK例如

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); 
    } 
    .... 
    .... 
+0

由于'setMyVector'仅复制引用,主叫变异'矢量'在以后的时间 –

+0

@SteveKuo这怎么可能?我保持update/set方法为'private',以便它只能在类中调用。 –

1

试试这个:

Collections.unmodifiableList(myList); 
0

通过使载体的实例为私有,并提供二传手私人吸气剂作为公众将在我看来,正确的路径。 为:

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

将readnoly实例,但是,它仍然会允许访问其他类调用添加/设置/删除的方法,但调用UnsupportedException这些方法的结果被提出。

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

0

其更好地给你Vector的副本,而不是给你的矢量的原始参考像以下:

Vector vector = // your vector object in your class 
public Vector<String> getMyVercorObject(){ 
    return (Vector<String>)vector.clone() ; 
} 
+0

我认为如果你能提一下你为什么倒是投票,那么它会更好。 –

+0

你会得到'ClassCastException'试图将'unmodifiableList'强制转换为'Vector' –

+0

好吧,我没有答复你的答案。虽然你的代码不会编译有两个原因。 –

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>()); 
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 
    } 
}