Iterator isEmpty() call causing noSuchElement exception?
Solution 1
visibleTiles.isEmpty()
just checks whether map is empty (or) it has any elements.
ile = visibleTiles.keySet().iterator().next();
retrieves next element from iterator.
You need to do hasNext()
check before doing next()
on iterator.
hasNext()
javadoc says
Returns true if the iteration has more elements. (In other words, returns true if next would return an element rather than throwing an exception.)
so, if no element is available and call next()
on iterator will return NoSuchElementException
.
On top of this, I think you really would like to do NOT empty check
while (!visibleTiles.isEmpty())) {
....
}
Solution 2
while (visibleTiles.keySet().iterator().hasNext())
creates a new Iterator
every time it is called*. If visibleTiles
is not empty, this will always be true, as the next method of the respective iterator is never called and the internal pointer never advances.
Iterators should be used like this:
Iterator<TileType> tileIt = visibleTiles.keySet().iterator();
while (tileIt.hasNext()) {
TileType tile = tileIt.next();
// ...
}
*The point here is that there may be several iterators referring to the same collection at the same time. Each iterator has its own internal state storing (not necessarily explicitly) which element was returned last and which shall be returned next by the next()
call. This can be useful, for example, do perform some operation on all pairs of elements from a collection, where two iterators are needed.
Solution 3
You can use com.google.common.collect.Iterables class for empty check on Iterable values.
Iterables.isEmpty(yourIterable)
Comments
-
kevinl almost 2 years
I currently have the following code
while (!visibleTiles.isEmpty())) { tile = visibleTiles.keySet().iterator().next(); if (tile != null){ bitmap = visibleTiles.remove(tile); if(bitmap != null && !containsKey(tile)){ //safe to recycle if tile cache is not actively holding it bitmap.recycle(); } } }
However, I get a NoSuchElementException crash on the line
tile = visibleTiles.keySet().iterator().next();
Is there a big difference in using the isEmpty() method and calling a hasNext() call? I know that hashmaps do not have a hasNext() call so I did the following:
while (visibleTiles.keySet().iterator().hasNext()) { tile = visibleTiles.keySet().iterator().next(); if (tile != null){ bitmap = visibleTiles.remove(tile); if(bitmap != null && !containsKey(tile)){ //safe to recycle if tile cache is not actively holding it bitmap.recycle(); } } }
Obviously, I know that I should just run the app and see if it crashes, but the issue is that it's difficult to reproduce the problem.
Thanks!