GC performance isn't the only thing you need to care about here. Iterating over an ArrayList<T> in Java already makes you chase pointers all over the place due to Java's lack of value types, which wrecks cache locality. ArrayList<Optional<T>> just makes you chase two pointers for each object instead.