Dónal
Dónal

Reputation: 187529

improved collection Iterator

Personally, I find the range of functionality provided by java.util.Iterator to be fairly pathetic. At a minimum, I'd like to have methods such as:

Though there are lots of other possibilities such as first() and last().

Does anyone know if such a 3rd party iterator exists? It would probably need to be implemented as a decorator of java.util.Iterator so that it can work with the existing java collections. Ideally, it should be "generics aware".

Thanks in advance, Don

Upvotes: 13

Views: 8343

Answers (11)

William
William

Reputation: 6428

You can get previous() easily by just using a java.util.ListIterator.

Peek at that point is easily implemented by doing a

public <T> T peek(ListIterator<T> iter) throws NoSuchElementException {
    T obj = iter.next();
    iter.previous();
    return obj;
}

Unfortunately it will be easier to have it as a utility method since each collection class implements their own iterators. To do a wrapper to get a peek method on each collection on some interface such as MyListIterator would be quite a lot of work.

Upvotes: 11

Kevin Bourrillion
Kevin Bourrillion

Reputation: 40851

I saw that someone linked to Google Collections, but no one mentioned that the method you are looking for is called Iterators.peekingIterator().

Still, it would be best if you could just use a ListIterator.

Upvotes: 2

PrinsValium
PrinsValium

Reputation:

public class Iterazor<T> {
  private Iterator<T> it;
  public T top;
  public Iterazor(Collection<T> co) {
    this.it = co.iterator(); 
    top = it.hasNext()? it.next(): null; 
  }
  public void advance() { 
    top = it.hasNext()? it.next(): null; 
  }
}

// usage

for(Iterazor<MyObject> iz = new Iterazor<MyObject>(MyCollection); 
    iz.top!=null; iz.advance())
  iz.top.doStuff();
}

Upvotes: 1

DJClayworth
DJClayworth

Reputation: 26856

The Java collections were written to provide a minimal set of useful functionality. This is a very good approach for code that has to be implemented by anyone implementing Java. Bloating an interface with functionality that might be useful can lead to a sizable increase in volume of code with improvements noticed only by a few. If peek() and previous() were part of the standard iterator that means everyone writing a new kind of Collection must implement it, whether it's sensible or not.

Iterators are also designed to work on things that physically cannot go backwards, making peek() and previous() both impossible.

Upvotes: 0

Paul Wicks
Paul Wicks

Reputation: 65550

As ykaganovich suggested, you might want to check out the google-collections stuff. There is definitely some support for some of the things you want, like peeking. Also, as some others have mentioned, implementing all of these things for all collections can be dangerous from a possibility or performance viewpoint.

Upvotes: 1

PierreBdR
PierreBdR

Reputation: 43254

There is a good damn reason the generic operators do not implement these features: they do not exist for all container. The typical example is a container representing some external data input, like a file seen as a stream. Each time you read a value you consume it and move the pointer forward, if you want it or not. If you impose these constraints on the generic iterators, then you loose the genericity of the iterators.

If you want a previous method, as suggested, use the ListIterator<>, which is then restricted to container behaving as lists.

Upvotes: 4

Draemon
Draemon

Reputation: 34711

It sounds like you might be better off using a Stack.

Upvotes: 0

Lou Franco
Lou Franco

Reputation: 89172

One thing I would look at is the Seq implementation in clojure

http://clojure.org/sequences

The implementation of the base classes are in Java and full source is available. Seqs are decorators on java iterators (take and implement java iterator interfaces) -- but they also provide their own interface which might be more of what you want -- or at least a starting point.

Upvotes: 3

Steve g
Steve g

Reputation: 2499

I haven't ever run into an issue where I've needed a peek(); Iterator has worked just fine for me. I'm curious how you're using iterators that you feel you need this added functionality.

Upvotes: 0

Lou Franco
Lou Franco

Reputation: 89172

I think the reason these aren't implemented is because they are non-trivial for some collections and would have large performance impact. I think it would be pretty simple for you to make this work for the collections you care about.

I also don't like that Java iterators have no way of getting the current value without moving it (and therefore you can't easily write code that branches based on the value, just passing the iterator -- you have to pass the value you now have as well).

Upvotes: 8

Related Questions