Improve this answer. Ajinkya Ajinkya Kumar Abhinav Kumar Abhinav 6, 2 2 gold badges 20 20 silver badges 32 32 bronze badges.
As it was already written, there are thousands of implementations. Champagne C. Champagne 4, 2 2 gold badges 22 22 silver badges 33 33 bronze badges. Keerthivasan Keerthivasan Uhm, even abstract classes can implement it — fge. Sign up or log in Sign up using Google. Sign up using Facebook. Sign up using Email and Password. Post as a guest Name. Email Required, but never shown. The Overflow Blog.
Does ES6 make JavaScript frameworks obsolete? Podcast Do polyglots have an edge when it comes to mastering programming Featured on Meta. Now live: A fully responsive profile. Notice that I have used the fully qualified names for the Scanner and File.
This obviates the need to import java. Notice that this implementation does not support the remove operation. When the remove method is invoked, an UnsupportedOperationException is thrown. And we want to avoid counting indices. That leaves just while loops as our only option. Recall the skeleton of a while loop:. For-each loops essentially keep looping while there are more items to process. So: we want to preserve these two functions, but we need to keep track of state to make them work properly.
Accordingly, we need to create a new object, whose sole responsibility is to help us iterate over tList. Do Now! At least it does start with a capital I! Notice the protocol: we always check hasNext before calling next. This ensures that we never overshoot the end of the list. So far, so good: we can describe the behavior of a for-each loop in terms of a while loop over an Iterator. But how does Java know what kind of iterator to construct?
After all, the ArrayListIterator in the sketch above really is specific to ArrayList s; if we want our for-each loops to work over other kinds of things, we need another mechanism. This is far more general than just working over ArrayList s — any class that implements Iterable can be used with a for-each loop.
This is yet another example of the power of good abstractions: by recognizing the common elements of iteration and being iterable, we can create a reusable notion that works wherever we choose to implement it.
This may seem a bit confusing, and it is. How many fenceposts are needed? Answer: seven , because you need a fencepost before the very first section of fence: XXXXXXX Likewise, in our Iterator protocol, there will be one more call to hasNext than there will be to next , because we call it before every call to next , and then once more to find out there are no more items.
Accordingly, when we call hasNext , the nextIdx field will refer to the index of the next item — starting at 0 — to be returned. And with those last few definitions, we can now use IList s in for-each loops, exactly as we could with ArrayList s. The concept of an Iterator is very flexible. Not every iterator needs to store an actual object from which it derives its data. Iterators simply represent sequences of values, and those values might just be computed on demand.
Much as we can have higher-order functions as implemented in Java by higher-order function objects , we can have higher-order iterators, that use the sequence of values from one iterator and produce a different sequence of values.
We can even define iterators over tree-shaped data. There are many plausible orders for traversing a tree. An in-order traversal , which recursively produces the left subtree of a node, then the node, then recursively produces the right subtree: D, B, E, A, F, C, G.
A pre-order traversal or a depth-first traversal , which produces the node, then recursively produces the left subtree of the node, then the right subtree: A, B, D, E, C, F, G. So, suppose we are given a reference to the node A above. What should go on the worklist? We need to process B and C in that order , so we add them to our worklist. On the subsequent call to next , we need to process B , so we produce B , and need to process D and E.
We still have to process C before we get to D or E because we are proceeding in breadth-first order , so we add D and E to the back of our worklist.
Our next item to process is C , which is at the front of our worklist. It looks like we need to be able to add items to the end of our list, and remove items from the front of our list. We are using our Deque as a queue , where items are added at the end of the queue and removed from the front. Think of a queue as standing in line at the supermarket: people queue up at the end of the line, and exit from the front of the line. Think of a stack as a pile of dishes: they are piled on top of each other, and removed from the top; the bottommost dish was the first one to be added, and the last one to be removed.
We have to swap the order of adding node. Recall that when we introduced for-each loops, they were a replacement for a recursive implementation of map over ArrayList s.
The while loop sketch above will work with any object that exposes these two functions as methods. This is a promise to provide a certain set of behaviors, so we should accordingly define a new interface. This interface is called an Iterator , and it is provided for us by Java itself. Its methods are slightly renamed from the sketch above:. The job of an Iterator is to keep track of whatever state is necessary to produce values one-at-a-time from a sequence, be it an ArrayList , an IList , a Deque , or whatever else we choose.
0コメント