Implement a class PeekingIterator that wraps an iterator over a list of integers and provides the following methods:
- PeekingIterator(iterable): Initializes the object with an iterable of integers.
- next(): Returns the next element and advances the iterator.
- has_next(): Returns True if there are more elements to iterate.
- peek(): Returns the next element without advancing the iterator.
All calls to next() and peek() are valid (i.e., there is always a next element when called).
Example 1
Input: actions = ["PeekingIterator", "peek", "next", "peek", "next", "has_next"] args = [[ [4, 5, 6] ], [], [], [], [], []]
Output: [None, 4, 4, 5, 5, True]
Explanation: Initialize with [4,5,6]. peek() returns 4. next() returns 4. peek() returns 5. next() returns 5. has_next() returns True (6 remains).
Example 2
Input: actions = ["PeekingIterator", "next", "peek", "next", "has_next"] args = [[ [10, 20] ], [], [], [], []]
Output: [None, 10, 20, 20, False]
Explanation: Initialize with [10,20]. next() returns 10. peek() returns 20. next() returns 20. has_next() returns False.
Constraints
Case 1
Input: actions = ["PeekingIterator", "peek", "next", "peek", "next", "has_next"] args = [[ [7, 8, 9] ], [], [], [], [], []]
Expected: [None, 7, 7, 8, 8, True]
Case 2
Input: actions = ["PeekingIterator", "next", "peek", "next", "has_next"] args = [[ [100, 200] ], [], [], [], []]
Expected: [None, 100, 200, 200, False]
Case 3
Input: actions = ["PeekingIterator", "peek", "next", "peek", "next", "next", "has_next"] args = [[ [1, 2, 3, 4] ], [], [], [], [], [], []]
Expected: [None, 1, 1, 2, 2, 3, True]