Iterate over values of a HashMap without creating any new objects to be Garbage Collected

hashmap, iteration, java

Solution

But this will create an Iterator object behind the scenes (I think?)

Yes it will.

The best I have come up with is this code:

  Object[] values = myMap.values.toArray();
  ...standard "int i" for loop on the array

But to be honest I am not sure what the GC will do with this array.

In fact this is going to be worse than using an `Iterator` explicitly or implicitly:

- The `toArray()` method allocates a new array and copies the value-set elements into it.

- The call to `values()` may instantiate a `Set` object.

- The call to `toArray()` internally calls `iterator()` on the value set object which creates a new `Iterator` instance.

So you are allocating an `Iterator` anyway, AND a temporary array, AND (possibly) a `Set` object.

I profiled the heap and the largest set of objects was `ArrayList$Itr` (not related to this `HashMap` example, but I am currently rewriting all enhanced for loops to standard for loops)

As you point out, that is a different case. But I still think you are barking up the wrong tree here. If you are using a recent HotSpot JVM, the cost of allocating and garbage collecting short-lived objects (i.e. ones that don't get tenured) is pretty small. Unless you have a specific reason to reduce the object allocation rate, all of your work may achieve little in terms of actual measurable performance improvement.

Problem

I am trying to iterate over the values of a HashMap in Java without creating any new objects that would need to be garbage collected. It is easy to iterate over values using enhanced for loops, like this: ``` for (Value v : myMap.values()) { .... } ``` But this will create an Iterator object behind the scenes (I think?) The best I have come up with is this code: ``` Object[] values = myMap.values.toArray(); ...standard "int i" for loop on the array ``` But to be honest I am not sure what the GC will do with this array. Is there a perfect way to do this, or is there a way to do this with one reusable object? EDIT: This is for an Android game, and there a lot of such loops that are creating objects and affecting performance. EDIT #2: For those who are doubting, my refactoring of just a portion of the most commonly called enhanced for loops, mostly on ArrayLists, has had a significant impact on memory usage based on jvisualvm heap profiling. Of course, part of this is probably because I have too many ArrayLists, or loop through them when it's not really necessary.

Original source