Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

From ArrayList<ArrayList<Object>> to fixed size array/list

I have this:

private ArrayList<ArrayList<Object>> models;

and in the constructor I have:

models = new ArrayList<ArrayList<Object>>();

Later, I do things like:

models.add(new ArrayList<Object>());

as well as other operations.

I want to make the external ArrayList to something with a fixed size (Array, List) and I am really lost to how I am going to write the declaration, initialization, addition, etc. because of the nested objects. Can someone save me time by answering this for me?

like image 448
John Avatar asked Jan 02 '18 10:01

John


2 Answers

You can use Arrays.asList() to created fixed sized Lists.

Examples:

A List of size 3, initialized with null values:

List<ArrayList<Object>> models = Arrays.asList (null,null,null);

A List of size 3, initialized with non-null values:

List<ArrayList<Object>> models = Arrays.asList (new ArrayList<Object> (),new ArrayList<Object> (),new ArrayList<Object> ());

A List of size 10, initialized with null values:

List<ArrayList<Object>> models = Arrays.asList ((ArrayList<Object>[])new ArrayList[10]);

Note that add operation is not supported for fixed sized lists. You'll have to use models.set(index,new ArrayList<Object>()) instead.

EDIT:

Here's another way to initialize the List using Streams:

List<ArrayList<Object>> models = Arrays.asList (Stream.generate (ArrayList::new).limit (10).toArray (ArrayList[]::new));
like image 164
Eran Avatar answered Oct 21 '22 19:10

Eran


A slightly more verbose - but generic-compatible way - of doing it is to extend AbstractList.

The methods you need to override are described in the Javadoc:

To implement an unmodifiable list, the programmer needs only to extend this class and provide implementations for the get(int) and size()methods.

To implement a modifiable list, the programmer must additionally override the set(int, E) method (which otherwise throws an UnsupportedOperationException).

So, implement these three methods, delegating to an ArrayList:

class FixedSizedList<T> extends AbstractList<T> {
  private final List<T> delegate;

  FixedSizedList(int size) {
    delegate = new ArrayList<>(Collections.nCopies(size, null));
  }

  public T get(int i) { return delegate.get(i); }
  public int size() { return delegate.size(); }
  public T set(int i, T e) { return delegate.set(i, e); }
}

Or, for that matter, just use an array:

class FixedSizedList<T> extends AbstractList<T> {
  private final Object[] array;

  FixedSizedList(int size) {
    array = new Object[size];
  }

  public T get(int i) { return (T) array[i]; }
  public int size() { return array.length; }
  public T set(int i, T e) {
    T old = (T) array[i];
    array[i] = e;
    return old;
  }
}
like image 25
Andy Turner Avatar answered Oct 21 '22 19:10

Andy Turner