Most Iterators should be placed on the stack anyway. If they are not and you have a random access collection like ArrayList you can use an index, but this is rarely needed.
If you are going to change code, perhaps Stream(s) are a better choice, these are also placed on the stack most of the time.
Reusing your objects can be confusing for other developers. You need to be careful with anything exposed via an API, however internally you can me more optimised.
In each case the default settings were used (i.e. no options were provided). In both Java 8 (Parallel GC) and Java 11+ (G1), As the GC was a small portion of the time, changing the GC wasn't expected to make a difference anyway.
The GC isn't involved with allocation, the expensive bit here. The GC handles the clean up.
The allocations create memory pressure that can easily saturate the bus to DDR if you are not careful.
This is where using a profiler like YourKit or Flight Recorder is your friend. It will show you the objects that can't be optimised away and where code bottlenecks are. It's hard to determine this in advance for Java.