I want to create an fixed size list in java, according to my searchings & readings from the internet i couldn't find that feature in java, However i want to create a fixed size list with 100 elements, when i want to add a new item it should remove 100th element, then adjust the index like this (99th element becomes the 100th element now(Indexes only)) and then my new element should add to the first index.
How to do such a thing in java?
You can have your collection class implement a List
and have it delegate to an internal Deque
.
Here is the add method:
// Note: This is the only important method to implement
// The rest of the methods delegate to the deque field
@Override
public boolean add(T item) {
// The first item falls off the deque if it's full
if (deque.size() == maxSize) {
deque.removeFirst(); // Remove the oldest element
}
return deque.add(item); // Add the new element to the end
}
Here are two classes; the FixedSizeDequeRunner
which contains a main
entry-point, and the FixedSizeDeque
collection class.
package org.example.collections;
import java.util.Arrays;
import java.util.List;
public class FixedSizeDequeRunner {
public static void main(String[] args) {
List<String> fixedDeque = new FixedSizeDeque<>(10);
for (int i = 0; i < 15; i++) {
fixedDeque.add("Item " + i);
}
int i = 0;
for (String item : fixedDeque) {
System.out.printf("Index %d: %s%n", i++, item);
}
System.out.printf("Fixed Size Deque: %s%n", fixedDeque);
// Convert to an array
String[] asArray = fixedDeque.toArray(new String[0]);
System.out.printf("Array: %s%n", Arrays.toString(asArray));
}
}
Here is a delegation pattern that defers to a Deque
:
package org.example.collections;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
public class FixedSizeDeque<T> implements List<T> {
private final int maxSize;
private final Deque<T> deque;
public FixedSizeDeque(int maxSize) {
this.maxSize = maxSize;
this.deque = new ArrayDeque<>(maxSize);
}
// Note: This is the only important method to implement
// The rest of the methods delegate to the deque field
@Override
public boolean add(T item) {
// The first item falls off the deque if it's full
if (deque.size() == maxSize) {
deque.removeFirst(); // Remove the oldest element
}
return deque.add(item); // Add the new element to the end
}
@Override
public boolean remove(Object o) {
return deque.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return deque.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends T> c) {
boolean modified = false;
for (T item : c) {
if (add(item)) {
modified = true;
}
}
return modified;
}
@Override
public boolean addAll(int index, Collection<? extends T> c) {
if (index < 0 || index > size()) {
throw new IndexOutOfBoundsException("Index out of bounds: " + index);
}
List<T> tempList = new ArrayList<>(this);
tempList.addAll(index, c);
if (tempList.size() > maxSize) {
tempList = tempList.subList(tempList.size() - maxSize, tempList.size());
}
deque.clear();
deque.addAll(tempList);
return true;
}
@Override
public boolean removeAll(Collection<?> c) {
return deque.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return deque.retainAll(c);
}
@SuppressWarnings("unchecked")
@Override
public T get(int index) {
if (index < 0 || index >= deque.size()) {
throw new IndexOutOfBoundsException("Index out of bounds: " + index);
}
return (T) deque.toArray()[index];
}
@Override
public T set(int index, T element) {
if (index < 0 || index >= deque.size()) {
throw new IndexOutOfBoundsException("Index out of bounds: " + index);
}
List<T> tempList = new ArrayList<>(deque);
T oldElement = tempList.set(index, element);
deque.clear();
deque.addAll(tempList);
return oldElement;
}
@Override
public void add(int index, T element) {
if (index < 0 || index > size()) {
throw new IndexOutOfBoundsException("Index out of bounds: " + index);
}
List<T> tempList = new ArrayList<>(deque);
tempList.add(index, element);
if (tempList.size() > maxSize) {
tempList = tempList.subList(tempList.size() - maxSize, tempList.size());
}
deque.clear();
deque.addAll(tempList);
}
@Override
public T remove(int index) {
if (index < 0 || index >= deque.size()) {
throw new IndexOutOfBoundsException("Index out of bounds: " + index);
}
List<T> tempList = new ArrayList<>(deque);
T removedElement = tempList.remove(index);
deque.clear();
deque.addAll(tempList);
return removedElement;
}
@Override
public int indexOf(Object o) {
int index = 0;
for (T item : deque) {
if (Objects.equals(item, o)) {
return index;
}
index++;
}
return -1;
}
@Override
public int lastIndexOf(Object o) {
int index = deque.size() - 1;
ListIterator<T> iterator = new ArrayList<>(deque).listIterator(deque.size());
while (iterator.hasPrevious()) {
if (Objects.equals(iterator.previous(), o)) {
return index;
}
index--;
}
return -1;
}
@Override
public ListIterator<T> listIterator() {
return new ArrayList<>(deque).listIterator();
}
@Override
public ListIterator<T> listIterator(int index) {
if (index < 0 || index > size()) {
throw new IndexOutOfBoundsException("Index out of bounds: " + index);
}
return new ArrayList<>(deque).listIterator(index);
}
@Override
public List<T> subList(int fromIndex, int toIndex) {
if (fromIndex < 0 || toIndex > size() || fromIndex > toIndex) {
throw new IndexOutOfBoundsException("Index out of bounds: " + fromIndex + " to " + toIndex);
}
return new ArrayList<>(deque).subList(fromIndex, toIndex);
}
@Override
public int size() {
return deque.size();
}
@Override
public boolean isEmpty() {
return deque.isEmpty();
}
@Override
public boolean contains(Object o) {
return deque.contains(o);
}
@Override
public Iterator<T> iterator() {
return deque.iterator();
}
@Override
public Object[] toArray() {
return deque.toArray();
}
@Override
public <T1> T1[] toArray(T1[] a) {
return deque.toArray(a);
}
@Override
public void clear() {
deque.clear();
}
@Override
public String toString() {
return deque.toString();
}
}