I'm a beginner in Java and I have to recieve values from such thing as Iterator<Iterator<Integer>>
. For example, we may have:
{{1, 2}, {3, 4}, {5, 6}}
The result of next()
should be 1
. If we try next()
one more time - 2
, then - 3
, 4
, etc. Like getting values from 1D array one by one, but from 2D array. We should not copy anything. So, I wrote some bad code below:
public class IteratorNext {
private Iterator<Iterator<Integer>> values = null;
private Iterator<Integer> current;
public IteratorNext(Iterator<Iterator<Integer>> iterator) {
this.values = iterator;
}
public int next() throws NoSuchElementException {
current = values.next();
if (!current.hasNext()) {
values.next();
}
if (!values.hasNext() && !current.hasNext()) {
throw new NoSuchElementException("Reached end");
}
return current.next();
}
}
That code is not correct, because result of next()
is 1
, then 3
, then 5
and because of exception here. How to fix this?
4 Answers 4
If you are using Java-8, you can take advantage of the flatMapToInt
function to iron out your 2D array into a 1D array (array2d
can be assumed to be a reference to your 2D array) :
Arrays.stream(array2d).flatMapToInt(Arrays::stream).forEach(System.out::println);
if you want to stick to your solution, you need to modify your next
method as follows :
public int next() throws NoSuchElementException {
int result = -1;
//Are we already iterating one of the second dimensions?
if(current!=null && current.hasNext()) {
//get the next element from the second dimension.
result = current.next();
} else if(values != null && values.hasNext()) {
//get the next second dimension
current = values.next();
if (current.hasNext()) {
//get the next element from the second dimension
result = current.next();
}
} else {
//we have iterated all the second dimensions
throw new NoSuchElementException("Reached end");
}
return result;
}
Comments
public static class IteratorNext {
private Iterator<Iterator<Integer>> values = null;
private Iterator<Integer> current;
public IteratorNext(Iterator<Iterator<Integer>> iterator) {
this.values = iterator;
}
public int next() throws NoSuchElementException {
if (current != null && current.hasNext()) {
Integer val = current.next();
return val;
}
if (values != null && values.hasNext()) {
current = values.next();
if (current != null && current.hasNext()) {
Integer val = current.next();
return val;
}
}
throw new NoSuchElementException("Reached end");
}
}
2 Comments
null
check on the current
in the third if
condition is not really required since current
represents an Iterator
that can never be null
.Each time you call next(), you have to deal with the result.
The first line of your next() method you skip the first element because you recall current.next() at the end of your next() method.
More generally speaking this code is not the right way to deal with collections. You have to analyze the problem in term of usage.
Comments
The problem is that each time you call next() you start with
current = values.next();
So at each call you skip to the next iterator, without trying to continue iteration on current.
Instead you should do something like
if(!current.hasNext())
current = values.next();
Comments
Explore related questions
See similar questions with these tags.
java-8
? There is a simpler way to do this then.