This is a follow up question for this question:
This is an implementation of an array that behaves like a list, granting me an easy and quick way to:
- quickly add items
- iterate over them without caring for empty spots in the array
- quickly remove iterated items
After following user rolfl answer I revised my class to this
import java.lang.reflect.Array;
import java.util.Iterator;
import java.util.stream.IntStream;
public class BucketArray<T> implements Iterable<T> {
private final T[] mItems;
private final int[] mSlots;
private int mSlotsTop = -1;
public final int size;
private int mIteratedIndex = -1;
@SuppressWarnings("unchecked")
public BucketArray(Class<T> cast, int size) {
this.size = size;
mItems = (T[]) Array.newInstance(cast, size);
mSlots = IntStream.range(0, size).toArray();
mSlotsTop = size - 1;
}
public int add(T item) {
if (item == null)
return -1;
if (mSlotsTop < 0)
return -1;
final int slot = popSlot();
mItems[slot] = item;
return slot;
}
public void addAll(T... items) {
for (T item : items)
add(item);
}
public T get(int i) {
if (i < 0 || i >= size)
throw new IndexOutOfBoundsException();
return mItems[i];
}
public int getIteratedIndex() {
return mIteratedIndex;
}
public boolean remove(int i) {
if (i < 0 || i > size)
return false;
if (mItems[i] == null)
return false;
mItems[i] = null;
pushSlot(i);
return true;
}
public void remove(T item) {
remove(indexOf(item));
}
public boolean removeIterated() {
return remove(mIteratedIndex);
}
public boolean isFull() {
return mSlotsTop == -1;
}
public boolean isEmpty() {
return mSlotsTop == size - 1;
}
public int numFreeSlots() {
return mSlotsTop + 1;
}
public int indexOf(T item) {
for (int i = 0; i < size; i++)
if (item == mItems[i])
return i;
return -1;
}
private int popSlot() {
return mSlots[mSlotsTop--];
}
private void pushSlot(int s) {
mSlots[++mSlotsTop] = s;
}
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private int index = -1;
{
if (mIteratedIndex != -1)
index = mIteratedIndex;
}
@Override
public boolean hasNext() {
do {
index++;
if (index >= size) {
mIteratedIndex = -1;
return false;
}
} while (mItems[index] == null);
return true;
}
@Override
public T next() {
mIteratedIndex = index;
return mItems[index];
}
};
}
}
Major changes:
add()
method now ignoresnull
and returns the index of the inserted item so it can be used withget()
andremove()
.- After some thought, the
remove()
method mostly used in the context of an iteration, so I addedremoveIterated()
method that removes the currently iterated item in the scope of an iteration being made. - Name of the class changed to
BucketArray
fromBagArray
because it sounds better.
Usage example in deleting duplicated integer values:
public static void main(String[] args) {
BucketArray<Integer> mBucket = new BucketArray<Integer>(Integer.class,20);
mBucket.addAll(10, 20, 30, 20, 20, 30, 10, 40);
// bucket is: 40, 10, 30, 20, 20, 30, 20, 10
for (int a : mBucket)
for (int b : mBucket)
if (a == b)
mBucket.removeIterated();
// bucket is now: 40, 10, 30, 20
}