简体   繁体   中英

Unmodifiable Vector in Java

I need to manage data in my program where Java-Vector suits the purpose as it is synchronized,provides dynamic size and fast random access through index.

But I want to make my Vector Read Only for other Program Classes and Read Write for my own Class.

I read about Collections.unmodifiableList() ,but if I make my Vector unmodifiable, it will become read-only to my class as well.

How can I solve this problem?

I read about Collections.unmodifiableList() , but if I make my Vector unmodifiable, it will become read-only to my class as well.

I think you misunderstand what that method does. In reality, it creates an unmodifiable wrapper for the existing list, leaving the original list modifiable.

So the way to handle your requirement is to do something like this 1 :

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

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

Anything that has access to myVector can still add and remove elements from it. The changes will be visible via the readonly object ... but "change" operations on that object won't work.

(The other approach is to create copies of the original Vector object, but I'm pretty sure that doesn't meet your requirements.)


1 - Note that the readOnly object is a List but not a Vector . This shouldn't be a problem unless you have made the mistake of declaring the getter as returning a Vector . If you've done that, and you can't correct the mistake, then you will need to create your own subclass of Vector along the line of Evgeniy Dorofeev's answer. Otherwise Collections.unmodifiableList(...) will do just fine.

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

If you really want an unmodifiable Vector (not just List) create a method as

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

Make vector a private member of your class. expose a public method to the callers which will get a reference to an unmodifiableCollection.

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

For use in your internal class, you can either reference the vector directly or create a private method which will return a reference to collection.

private Vector getMyVector(){
         return yourVector ;
    }

I think if you make your Vector as private member attribute in your along with all write methods as private while read methods as public , you would be OK eg

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

By making the vector instance as private and providing setter as private with getter as public would be the correct path in my opinion. For the :

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

it will readnoly instance, however, it will still allow the access to other classes to call add/set/remove methods but calling these methods results in UnsupportedException being raised.

Also, based on your requirement, you are looking for the updation of the vector / addition of new elements in it. So may by look for concurrent package to make it safer in doing so.

Its better to give copy of your Vector rather than giving original reference of your Vector Like following:

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

The best way is to use Vector internally, only expose mutations (add, remove, etc) using methods, and only return an unmodifiable view using an interface ( List ). Such an implementation might look like this (for example sake let's say the elements are strings):

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

In this way your class has full access to the list, while external entities can only mutate using the public methods.

Note that Vector is pretty much not used. If you require a thread safe list then consider ArrayList in conjunction with synchronizedList :

private final List<String> list = Collections.synchronizedList(new ArrayList<String>());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM