How to implement a fixed size "list" in Java?

12,356

Solution 1

I'd write a wrapper class around an ArrayList, and in the add and addAll methods, I'd check for the list's size before adding new elements. If you have reached the maximum size, you can then throw an exception (or do nothing, depending on what you really want to do in your code).

Here's a short example:

public class SizeLimitedArray<E> implements java.util.List<E>
    {
    private static final int DEFAULT_SIZE_LIMIT = 10;
    private ArrayList<E> myList;
    private int maxSize;

    public SizeLimitedArray ()
        {
        this (DEFAULT_SIZE_LIMIT);
        }

    public SizeLimitedArray (int size)
        {
        myList = new ArrayList<E> (size);
        maxSize = size;
        }

    @Override
    public boolean add (E objectToAdd)
        {
        if (myList.size () > maxSize)
            {
            throw new IllegalStateException ("The array is full");
            }

        return myList.add (objectToAdd);
        }

    @Override
    public boolean addAll (Collection collectionToAdd)
        {
        if (myList.size () + collectionToAdd.size () > maxSize)
            {
            throw new IllegalStateException ("The array is full");
            }

        return myList.addAll (collectionToAdd);
        }

    // Rest of class omitted for brevity
    }

Solution 2

Arrays.asList(T ...) Returns a fixed-size list backed by the specified array

Object[] array = new Object[10];
List<Object> fixedList = Arrays.asList(array);

Solution 3

You could use an array, or an ArrayList<E> pre-initialized with the desired size.

If you want to actively prevent the expansion of the list, then using an array is probably the easiest.

Solution 4

Just implement your own. You could use a proxy-based approach. Define your own list that is backed by an ArrayList. Make the internal list private. Also implement a simple limit field that has a default and also can be set via a constructor.

Your list will implement List, and for every method that modifies the internal list, increment and decrements the count appropriately. If the size exceeds the limit, throw some sort of exception. Something like

public class FixedList implements List {
    private ArrayList<E> list = new ArrayList<E>();
    private int limit = 10; // default

    FixedList(){} // default constructor

    FixedList(int limit) {
        this.limit = limit;
    }

    public boolean add(E object) {
       if (this.list.size() == limit - 1) {
           // throw some sort of LimitExceeded Runtime Exception
       }

       this.list.add(object);
    }
    ...
}

You will have to work on the generics, and remember to support the cases where multiple things are added at once addAll.

Solution 5

Well you could inherit from class ArrayList for example and reimplement the add method to not be able to add past a given amount of elements. Or, even better as pointer out by Laf, use composition:

public class MyArrayList<T> {
     private ArrayList<T> innerList;
     private int maxSize;

     public boolean add(T item) {
         if(innerList.size() < maxSize) {
             return innerList.add(item);
         } else {
             return false;
         }
     }
}
Share:
12,356
mre
Author by

mre

Updated on July 28, 2022

Comments

  • mre
    mre almost 2 years

    Since the Java core library doesn't have such a collection, would an array be the best option, especially if one doesn't want to rely on third-party libraries?

  • mre
    mre over 12 years
    But if I add an object to the ArrayList instance that would cause it to exceed its size, won't it automatically expand?
  • NPE
    NPE over 12 years
    @mre: If you do, it will. Are you saying you want to actively prevent yourself from doing this?
  • mre
    mre over 12 years
    @aix, Yes, I want to actively prevent myself from doing this.
  • mre
    mre over 12 years
    That's kind-of where I was thinking I'd have to go if I didn't want to use an array.
  • Laf
    Laf over 12 years
    I wouldn't recommend inheritance in this case, but a wrapper class. Overriding the add method might create more problems, because you become dependent of the ArrayList implementation. This is something Josh Bloch mentions in his Effective Java book.
  • NPE
    NPE over 12 years
    @mre: Fair enough. In that case, I personally would stick with an array.
  • Tudor
    Tudor over 12 years
    @mre: I've posted an example.
  • mre
    mre over 12 years
    So, if I attempt to add another object to fixedList which already contains 10 objects, will it throw an exception or just silently fail?
  • Aviram Segal
    Aviram Segal over 12 years
    add will give you UnsupportedOperationException, you can only use set and get, basically behaves like an array.
  • Voo
    Voo over 12 years
    So we take an ArrayList that was implemented to allow us to extend the size of arrays dynamically and then change its behavior so we can't do that anymore? Well yes not not x is the same as x, but that's rather pointless isn't it?
  • hvgotcodes
    hvgotcodes over 12 years
    I'm not sure what your point is. Are you saying his custom list should be backed by an array instead?
  • Aviram Segal
    Aviram Segal over 12 years
    Overkill, this is pretty much what Arrays.asList implements itself
  • Voo
    Voo over 12 years
    Well, you removed all additional functionality that ArrayList added over a simple array, so we could just use the array itself - or if we need the add and co functions yes just backing it up by an array would be simpler too.
  • hvgotcodes
    hvgotcodes over 12 years
    yeah that's a valid approach, although I disagree what I've "removed all additional functionality...". I personally would use a List over an array because I don't want to have to maintain the pointer to the current index and all that, and also for generics, but OP could use an array if it suits his purposes.
  • Rob Hruska
    Rob Hruska over 12 years
    It doesn't offer access to all list methods, though (i.e. it doesn't implement any sort of list) - particularly index-based accessing methods, which (for me anyway) would be the main reason to be using a list in the first place.
  • Perception
    Perception over 12 years
    True, I updated my answer to reflect that it really implements Collection operations, not List.