package com.freetymekiyan.algorithms.level.medium;
import java.util.Iterator;
/**
* Given an Iterator class interface with methods: next() and hasNext(), design and implement a PeekingIterator that
* support the peek() operation -- it essentially peek() at the element that will be returned by the next call to
* next().
* <p>
* Here is an example. Assume that the iterator is initialized to the beginning of the list: [1, 2, 3].
* <p>
* Call next() gets you 1, the first element in the list.
* <p>
* Now you call peek() and it returns 2, the next element. Calling next() after that still return 2.
* <p>
* You call next() the final time and it returns 3, the last element. Calling hasNext() after that should return false.
* <p>
* Hint:
* <p>
* Think of "looking ahead". You want to cache the next element.
* Is one variable sufficient? Why or why not?
* Test your design with call order of peek() before next() vs next() before peek().
* For a clean implementation, check out Google's guava library source code.
* <p>
* Follow up: How would you extend your design to be generic and work with all types, not just integer?
* <p>
* Company Tags: Google, Apple, Yahoo
* Tags: Design
* Similar Problems: (M) Binary Search Tree Iterator, (M) Flatten 2D Vector, (M) Zigzag Iterator
*/
public class PeekingIterator implements Iterator<Integer> {
private Integer next;
private Iterator<Integer> iter;
/**
* Peeking iterator is based on normal iterator.
* Just a wrapper class.
* Use a variable to cache the next element.
*/
public PeekingIterator(Iterator<Integer> iterator) {
// initialize any member here.
this.iter = iterator;
if (iterator.hasNext()) {
next = iterator.next();
}
}
/**
* Just return the cached element.
*/
// Returns the next element in the iteration without advancing the iterator.
public Integer peek() {
return next;
}
/**
* Return next value.
* If iterator still has more elements, update next with next.
* If iterator don't have any more, set next to null.
*/
// hasNext() and next() should behave the same as in the Iterator interface.
// Override them if needed.
@Override
public Integer next() {
int res = next;
next = iter.hasNext() ? iter.next() : null;
return res;
}
/**
* Just check next.
*/
@Override
public boolean hasNext() {
return next != null;
}
}