user2618929
user2618929

Reputation: 1629

List with max elements

I would like to create a list in java that while adding new element, will check if limit was reached. If it was, delete oldest element.

I was thinking about making child of ArrayList and overriding add(Object). In there i would make that:

if(size() + 1 > MAX)
    remove(get(0));
super.add(newObject);

Any better way?

Upvotes: 3

Views: 2263

Answers (6)

njzk2
njzk2

Reputation: 39406

What you describe is a circular fifo buffer. You can use Apache Commons-collections implementation.

See Commons Collections and CircularFifoBuffer for documentation

Upvotes: 1

Martijn Courteaux
Martijn Courteaux

Reputation: 68857

Make your own class that does the job. Keep track of two variables. One for that indicates the zero element and one that holds the position for the next element.

public class MyList<T>
{
    private T array[];
    private int first;
    private int next;
    private int count;

    public MyList(int count)
    {
        array = new T[count];
    }

    public void add(T obj)
    {
        array[next++] = obj;
        next %= array.length;
        if (count == array.length)
        {
            zero = (zero + 1) % array.length;
        } else count++;
    }

    public T get(int index)
    {
        return array[(zero + index) % array.length];
    }
}

Upvotes: 0

Johannes Pfeifer
Johannes Pfeifer

Reputation: 211

You could use a Deque:

private final int LIMIT = 10;

private Deque<String> queue = new ArrayDeque<String>(LIMIT);

public void addToList(final String element) {
   Deque<String> queue = new ArrayDeque<String>(LIMIT);
   if (!queue.offer(element)) {
      queue.removeFirst();
      queue.offer(element);
   }
}

Upvotes: 0

adi
adi

Reputation: 1741

IMO, you should be using arrays with a list wrapper. You can then do whatever you want. You can also add methods e.g. get that returns a List.

Upvotes: 0

DeltaLima
DeltaLima

Reputation: 5944

You could do it in the way that you have described but the performance of such a List would be low. Imagine that the limit has been reached and you remove the first element. Under the hood this would involve copying all elements of the underlying array one index up. Then the new element is added to the last index. Especially the copying of all elements is costly

Alternatively you could use a LinkedList, which is more efficient for these kind of operations.

Another way would be to write you own class to implement a Circular Buffer. This is basically an array of size MAX. You have to keep an index of the first element and the number of elements in the array. When you add an element, you check whether the number of elements equals MAX, if so, you overwrite the first element and increase the index of the first element by one. Indexed getters and setters need to take into account the offset of the first element as well, but this is not overly complicated.

The best choice depends on your use case. If you have to do a lot of inserts and deletes at random places in the list, LinkedList is definitely the way to go. If you only want to add items to the end and removing the head, the circular buffer is very efficient.

Upvotes: 0

devrobf
devrobf

Reputation: 7213

There are probably a number of solutions to this, but I think that yours is a suitable approach if you make one change: your underlying implementation class should be a LinkedList, not an ArrayList. The reason is that when you call remove on an ArrayList every element after the removed value must be shifted up (making remove(0) the very worst case!). However this is not a problem for a LinkedList.

Upvotes: 5

Related Questions