我需要在我的程序中管理数据,其中 Java-Vector 适合目的,因为它是同步的,通过索引提供动态大小和快速随机访问。
但我想让我的向量对其他程序类只读,对我自己的类读写。
我读过Collections.unmodifiableList()
,但如果我让我的Vector
不可修改,它也将变成我的班级只读。
我怎么解决这个问题?
我需要在我的程序中管理数据,其中 Java-Vector 适合目的,因为它是同步的,通过索引提供动态大小和快速随机访问。
但我想让我的向量对其他程序类只读,对我自己的类读写。
我读过Collections.unmodifiableList()
,但如果我让我的Vector
不可修改,它也将变成我的班级只读。
我怎么解决这个问题?
我读到了
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
。如果您已经这样做了,并且无法纠正错误,那么您将需要按照Vector
Evgeniy Dorofeev 的答案创建自己的子类。否则Collections.unmodifiableList(...)
会做得很好。
使其成为private
您的类的成员,并且仅提供返回向量的不可变版本的 getter,作为public
访问它的一种方式,使用您提到的函数 ( Collections.unmodifiableList()
)。
如果您真的想要一个不可修改的向量(不仅仅是列表),请创建一个方法
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
}
}
试试这个:
Collections.unmodifiableList(myList);
使 vector 成为您班级的私人成员。向调用者公开一个公共方法,该方法将获得对 unmodifiableCollection 的引用。
public Vector getVector(){
return Collections.unmodifiableList(yourVector) ;
}
为了在您的内部类中使用,您可以直接引用向量或创建一个private
方法来返回对集合的引用。
private Vector getMyVector(){
return yourVector ;
}
我想如果你把你的Vector
as private
member 属性放在你的write methods
asprivate
中,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);
}
....
....
在我看来,通过将向量实例设为私有并将 setter 设为私有而将 getter 设为公开将是正确的路径。为了 :
List<T> readOnlyList = Collections.unmodifiableList(myList);
它只会读取实例,但是,它仍然允许访问其他类来调用 add/set/remove 方法,但调用这些方法会导致引发 UnsupportedException。
此外,根据您的要求,您正在寻找矢量的更新/在其中添加新元素。因此,可以通过寻找并发包以使其更安全。
最好提供 Vector 的副本,而不是提供 Vector 的原始参考,如下所示:
Vector vector = // your vector object in your class
public Vector<String> getMyVercorObject(){
return (Vector<String>)vector.clone() ;
}
最好的方法是在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>());