How to make a 2D ArrayList immutable?

In the project I'm working on, I have a 2D ArrayList that represents some data:

private ArrayList<ArrayList<T>> data = null;

Now I need to return this ArrayList to some object so that the object can check it, but does not modify it.

In the next article, I found that a 2D ArrayList needs to be wrapped in a separately non-modifiable wrapper, but it does not mention how to do this:

Is an unmodifiable wrapper for java collections thread safe?

So my problem is: how to return an immutable 2D ArrayList from an existing 2D ArrayList? And besides, what is the fastest way, since the data can be large in practice?

Thanks for all the inputs!

+5
source share
5 answers

Use the method Collections.unmodifiableList:

ArrayList<ArrayList<String>> source = new ArrayList<ArrayList<String>>();
List<ArrayList<String>> out = Collections.unmodifiableList(source);

Calling Collections.unmodifiableListin a collection sourcedoes not make each nested list unmodified. You will need to do this recursively in the list if you want all the nested lists to be unmodifiable. So:

ArrayList<ArrayList<String>> source = new ArrayList<ArrayList<String>>();
List<List<String>> temp = new ArrayList<List<String>>();
for (ArrayList<String> list : source) {
    temp.add(Collections.unmodifiableList(list));
}
List<List<String>> out = Collections.unmodifiableList(temp);    
+1
source

I would recommend creating a wrapper class that handles issues with variability, and not List<List<T>>throughout the code base. You can force this class to implement the List interface so that clients can use it as a list, but the underlying data need not be a list of lists (it could even be an array or arrays).

, . Java , , , .

+1

.

public class ImmutableMatrix<T>
{
    private ArrayList<ArrayList<T>> matrix;

    public ImmutableMatrix(ArrayList<ArrayList<T>> matrix)
    {
        this.matrix = matrix;
    }

    public T get(int x, int y)
    {
        return matrix.get(y).get(x); // Maybe you want to swap x and y
    }

    public int height()
    {
        return matrix.size();
    }

    public int width(int y)
    {
        return matrix.get(y).size();
    }

}

, , x y.
level0 level1.

, . :

public Matrix<T> returnInspectData()
{
     return new Matrix(data); 
}
+1

, :

private ArrayList<ArrayList<T>> data = (put your data here);


ArrayList<ArrayList<String>> temp = new ArrayList<ArrayList<String>>();
for (ArrayList<String> l : data) {
    temp.add(Collections.unmodifiableList(l));
}
return Collections.unmodifiableList(temp);

- O (n) n m


- ad-hoc , , - String[][] -, . , , List<List<String>>, , .

+1

You can use Collections.unmodifiableList( ... )that does what you want. However, this only works for one list, so you have to do this for internal lists as well.

Another option would be a 2D array. Alternatively, you can use a wrapper class as already suggested.

0
source

All Articles