wood burning stoves 2.0*
The moose likes Java in General and the fly likes Collection Cursor? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Collection Cursor?" Watch "Collection Cursor?" New topic
Author

Collection Cursor?

Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8013
    
  22

I've been mucking about with collections quite a bit recently; and I've come to the conclusion that there's a major gap in the definition of Iterators - more specifically, between an Iterator and that monstrosity known as ListIterator.

I had a little discussion with Jeff about it in this thread (don't bother to check it; it's currently running at around 340 posts) and rapidly came to the conclusion that I wasn't explaining myself very well. I've therefore created this page, which hopefully sets out my ideas a bit more clearly.

I'd like to get people's reactions to it. Am I wrong? Is it too much? Has someone else also come to the same conclusion? I'm kind of interested in creating a JSR for it unless the verdict is that I'm completely around the twist; so I'd appreciate any input.

Thanks in advance.

Winston

Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

I skimmed your proposal, and I still sit in pretty much the same spot as I did before, which is mainly that I don't get the benefit of a single next() method a N direction indicators vs. N next()/prev()/up(), etc. methods.

Except maybe I finally twigged to why you prefer next-plus-direction, or at least part of it. Is it that for the common use case of picking a starting location and direction and going from one end to the other along that axis, you'd rather just deal with setting the direction once at the beginning of the iteration, and then always calling the same method for traversal?

E.g.:



If this is what you're talking about, I can see that. It lets us decouple specifying setting the direction of the iteration from actually performing the iteration in the chosen direction. We could, for example, create an iterator with the appropriate direction and then pass it to some other method that only has to know and care about getting the "next" item, without having to worry about whether it's in the forward, down, or left direction, and hence that method always just calls next(). Even in cases where it's all done in one method, if we decide we want to go from the other end, we just change which direction and starting point we set for our iterator, and leave the iteration loop alone. Kind of like declaring List<X> list = new AraryList<X>(); for a local variable. We don't gain much practically from that decoupling, but it does reveal a bit more about our design, as a sort of self-documentation.

Sorry it's taken me so long to get what you were talking about. I was focusing too much on, "I'm iterating this list, and I know which direction I want to go, so what's the difference if I call iterator(UP) + next() or iterator3D() + up().

I will say that outside of this (admittedly most common) use case, I still don't see any benefit, but maybe by the time you get it pushed through and it's available in Java 11 I'll eventually have caught on.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8013
    
  22

Jeff Verdegan wrote:Except maybe I finally twigged to why you prefer next-plus-direction, or at least part of it. Is it that for the common use case of picking a starting location and direction and going from one end to the other along that axis, you'd rather just deal with setting the direction once at the beginning of the iteration, and then always calling the same method for traversal?

Now you're getting it.

Like I say, I think Iterator has always had an implied direction; it's just never been explicitly stated. Separating out the direction from what you want to do also allows you to create a mini-API of "things I'd like to do next".

We could, for example, create an iterator with the appropriate direction and then pass it to some other method that only has to know and care about getting the "next" item, without having to worry about whether it's in the forward, down, or left direction, and hence that method always just calls next(). Even in cases where it's all done in one method, if we decide we want to go from the other end, we just change which direction and starting point we set for our iterator, and leave the iteration loop alone. Kind of like declaring List<X> list = new AraryList<X>(); for a local variable. We don't gain much practically from that decoupling, but it does reveal a bit more about our design, as a sort of self-documentation.

Absolutely. I don't think I could have put it any better.

I will say that outside of this (admittedly most common) use case, I still don't see any benefit, but maybe by the time you get it pushed through and it's available in Java 11 I'll eventually have caught on.

I guess one of my main thoughts is that if direction isn't constrained to simply 'forwards' and 'backwards', you can create collections that are not specifically linear.

I could imagine, for example, a Matrix or Grid class that extends from Table; or an iterator that allows a grid to be traversed "taxi-driver" style; or two files involved in a diff operation to be traversed in "stepping-stone" sequence (although that would probably involve extra logic).

It just seems to me that direction is an essential part of an Iterator; it's just been ignored (or assumed) up to now.

Winston
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Winston Gutkowski wrote:
I could imagine, for example, a Matrix or Grid class that extends from Table; or an iterator that allows a grid to be traversed "taxi-driver" style; or two files involved in a diff operation to be traversed in "stepping-stone" sequence (although that would probably involve extra logic).

It just seems to me that direction is an essential part of an Iterator; it's just been ignored (or assumed) up to now.


Not even necessarily just direction, but magnitude. Taking what you're saying a step further, we can view an Iterator as a tool for taking unit steps along a vector, where we define the direction and magnitude of one step.

For instance, on an infinite chessboard, a knight has 8 possible moves. Call the directions _1OCLOCK, _2CLOCK, 4, 5, 7, 8, 10, 11. Or maybe NNE, ENE, ESE, SSE, SSW, WSW, WNW, NNW. So if we do new KnightIterator(NNE) then every call to next() moves us 2 squares forward and 1 to the right.

Not that I can see much practical applicability for that particular use case (and the analogy kind of breaks down when we try to apply it to other pieces), but it was the first one that popped to mind as an example of a general case of what I think you're talking about.

So, on the one hand, I do think I finally understand what you're driving at. And I do see the utility of decoupling specifying the direction from taking a step in the specified direction. I might use that for simple forward/backward iterators. On the other hand, blowing it out to these more general hypothetical cases give me a slight taste of over-engineering. I can't recall ever having had a need for such a thing. Of course, that doesn't mean others won't have such a need. It just seems like we might be getting close to YAGNI territory.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8013
    
  22

Jeff Verdegan wrote:Not even necessarily just direction, but magnitude. Taking what you're saying a step further, we can view an Iterator as a tool for taking unit steps along a vector, where we define the direction and magnitude of one step.

I have to admit, when I first read it, I liked the idea; but on balance I think that would be stretching the notion of an Iterator, which is to traverse elements. And it seems to me that what you suggest could easily be built on top of a Traversor anyway.

So, on the one hand, I do think I finally understand what you're driving at. And I do see the utility of decoupling specifying the direction from taking a step in the specified direction. I might use that for simple forward/backward iterators. On the other hand, blowing it out to these more general hypothetical cases give me a slight taste of over-engineering. I can't recall ever having had a need for such a thing. Of course, that doesn't mean others won't have such a need. It just seems like we might be getting close to YAGNI territory.

I guess it depends on whether you see the utility of a collection that is more than just linear. I also reckon that part of it is about getting it right, as opposed to just "making do with something that works" - although I'm sure we've both been guilty of that - I just think that a foundation hierarchy should be held to higher standards.

Winston
 
 
subject: Collection Cursor?