0

I am experienced in other languages but very new to Java. As an optimisation for a specific situation, I'm trying to implement an iterable container class from an array, as I know my container will hold a maximum of 4 items at a time, and those items each belong in a specific index, not first in gets the lowest index available.

To save me checking for null when I iterate over the list, I only want the non-null values returned for iteration... Would the below override of 'iterator()' work? And is there any chance the garbage collector going to clear up the iterable list I return before I get to iterate over it? Or is there a better way to achieve this maybe?

class FixedArray<T> implements Iterable<T> {

    FixedArray() {}

    public void add(byte index, T item) {
        array[index] = item;
    }

    @Override
    public Iterator<T> iterator() {
        List<T> listWithoutNull = new ArrayList<>();
        for (Item item: array) {
            if (item != null) {
                listWithoutNull.add(item);
            }
        }
        return listWithoutNull.iterator();
    }

    private final T[] array = { null, null, null, null };
}
Iron Attorney
  • 1,003
  • 1
  • 9
  • 22
  • 1
    in such situation why do you need a `List` - maybe use `Set` instead – m.antkowicz Aug 31 '19 at 14:14
  • 1
    "*... as I know my container will hold a maximum of 4 items at a time, and those items each belong in a specific index, not first in gets the lowest index available.*" - Why not create a class with four attributes instead? – Turing85 Aug 31 '19 at 14:16
  • Is that Set inside the iterator method replacing List listWithoutNull? And what would be the advantage? – Iron Attorney Aug 31 '19 at 14:17
  • @Turing85 good question, because the flattened indexes is encoded with basic 2d positions for the purpose of quad tree positional identification – Iron Attorney Aug 31 '19 at 14:18
  • Ie. 00 = bottom left, 01 = bottom right, 10 = top left, 11 = top right – Iron Attorney Aug 31 '19 at 14:19
  • 1
    @IronAttorney and do you think this is more readable or easier to understand than `public class Square { private Point bottomLeft; private Point bottomRight; private Point upperLeft; private Poiint upperRight; }` ? – Turing85 Aug 31 '19 at 14:25
  • No, but mutually exclusive declerations of QuadTreeNodes are not useful to me. I need the positionally encoded indices as I stated above. This is the only performance bottleneck in my application, and I wish to resolve it. – Iron Attorney Aug 31 '19 at 14:36

1 Answers1

2

Would the below override of 'iterator()' work?

Yes, why not? Overriding iterator() is perfectly fine. However, this is not an efficient implementation. I would write something like this:

@Override
public Iterator<T> iterator() {
    return Arrays.stream(array).filter(Objects::nonNull).iterator();
}

Here, no intermediate collection will be created, so no overhead.

And is there any chance the garbage collector going to clear up the iterable list I return before I get to iterate over it?

No, the garbage collector is not allowed to do this while you are holding a strong reference to the Iterator object (unless your Iterator implementation uses something like weak references inside but this is not your case).

ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155