Reputation: 1629
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
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
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
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
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
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
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