Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In Java, most people expect that each call to Iterator.next() will return a distinct object. This has led some of us to define an alternative model which we called a 'cursor'. (Note that others use the term 'cursor' to draw a different distinction.) The pattern of a cursor is:

class SomeCursor {
    boolean hasNext();
    void next();
    type1 getItem1();
    type2 getItem2();
 }

In other words, it is perfectly clear that the same object evolves at each step in the iteration.

The problem on my hand right now is to also support situations, like web services, in which we absolutely do want distinct objects so that we can ship a collection of them around.

It pains me to imagine pairs of classes (a cursor and a bean) that have to be maintained in parallel, and I'm casting about for alternatives.

Here's one idea, and I wonder if anyone else out there has seen a better one.

  1. You make an interface consisting of the 'get' methods for an object with all the items in it.
  2. You define the cursor as implementing that interface and also hasNext & next.
  3. You dynamically create the bean objects using one of the major dynamic code-gen libs on the fly to create a class with the obvious fields and get methods, plus set methods if needed to make something like JAX-B happy.

edit: for those who are not following, I recommend a read of http://lucene.apache.org/java/2_4_0/api/org/apache/lucene/analysis/TokenStream.html. Also compare with http://download.oracle.com/javase/6/docs/api/java/sql/ResultSet.html, which is an example of this 'cursor' approach.

Note in Lucene an API that iterates over a sequence of objects, allow the caller to specify whether to deliver the new data to a new object or the same old object each time.

Yes, it is possible to define an Iterator<T> that returns the same thing ever time, but we have concerns that people will use this as a gun to shoot their toes off. Thus the preference for the JDBC-ish pattern.

share|improve this question
    
This is not an answer, but Rich Hickey, the author of the Clojure language has commented on the fact that Javas and C#'s iterators are weak in that they do not allow one to peek without popping, or some other limitation. Clojure has solved this problem. Perhaps Java is not the language that you want to use? blip.tv/clojure/clojure-sequences-740581 –  Job Aug 22 '11 at 17:55
    
Maybe you want to watch/read this : okolovich.info/andrei-alexandrescu-iterators-must-go –  deadalnix Aug 22 '11 at 17:59
    
Do you have a good reason for not returning distinct objects? I can't tell whether you're just paranoid about garbage or whether there's a system limitation you haven't mentioned. –  Peter Taylor Aug 23 '11 at 13:03
    
@Job not my decision. Customers are such an inconvenience. –  bmargulies Oct 20 '11 at 16:26
    
@PeterTaylor The entire lucene community has apparently decided to be paranoid about garbage/allocator overhead, and that's who we deliver to, and that's their view. –  bmargulies Oct 20 '11 at 16:27

3 Answers 3

Forgive me if I'm not quite grasping what you're after, but it does seem as if you're conflating the concepts of Iterator and Factory/Builder.

Let me just lay out some thoughts here.

The Iterator pattern works well for a homogenous collection of objects that you want to hand out through a common interface. For example, you have a collection of Strings and you want them dealt out in a particular order so you use a Comparator (behind the scenes) and your consuming code only has to call next() a few times to achieve it's objective.

The Factory pattern creates an instance of an Object according to a given specification - sometimes provided as arguments, sometimes inferred. The Builder pattern is similar but is usually geared towards completing a single step along the way to the completion of an instance of a composite collection of Objects.

It seems from your code example that you want a mechanism that allows you to create an instance of an Object (of varying type) in response to a given number of calls. Perhaps a sequence like this:

next() -> getType1() -> String with "Hello"
next() -> getType2() -> Integer with 4
next() -> getTypeN() -> some function applied -> some type returned

and so on.

If this is what you're after, then this approach violates the Principle of Least Surprise. As a developer if an object is being quietly mutated behind the scenes, I'd like to know about it since I want to know the threading and performance issues that could arise.

Since the problem you appear to face is one of maintaining a collection of objects between stateless web calls you're probably better off using a simple List and provide the index to the current entry as part of the response to the client. When the client requests the contents of the List simply hand it to JAXB to marshal it into XML/JSON (it'll use an Iterator).

This approach keeps your code simple, and therefore prevents developers after you looking at the code and saying WTF?

share|improve this answer

I really don't see the difference between what you have there and an of Iterator<T>. The fact that you want to recycle the underlying instance on each iteration is still legal, if ill advised.

Might be worth watching josh bloch's last puzzler presentation. one of the puzzles evoles around the EnumMap.entries() iterator recycling the same instance of Map.Entry for each entry, it certainly breaks the principle of least surprise.

share|improve this answer
1  
Joshua's puzzlers are great and in fact I'd recommend grabbing his Effective Java 2nd ed which will help you avoid some nasty gotchas in the language. –  Martijn Verburg Aug 23 '11 at 9:51
    
This isn't an answer. It's a comment on my question. –  bmargulies Oct 20 '11 at 16:27

It looks to me like you are mixing the concept of iterators with the concept of Java bean properties.

If you have an instance of a bean and you want to iterate through its properties, then there are a number of libraries that will help you do this, like the Apache commons BeanUtils, and Beanlib:

http://commons.apache.org/beanutils/

http://beanlib.sourceforge.net/

share|improve this answer
    
No I am not iterating through the properties. I am iterating through instances. –  bmargulies Aug 23 '11 at 0:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.