Hi,
I have a similar situation as demonstrated below. I cannot find a
proper solution to make method iterator() work properly. It works with
the custom interface Iterable2 (see below). I tried several
alternatives I could think of but to no avail (see comments in code).
Any other ideas? Or am I running into a limitation of Iterable?
Research did not turn up much useful information for this situation.
Thanks for any feedback!
Kind regards
robert
package generics;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
// does not work because: The type WrappedTest cannot extend or
implement Iterable<? extends Map.Entry<K,V>>. A supertype may not
specify any wildcard
// public class WrappedTest<K, V> implements Iterable<? extends
Map.Entry<K, V>> {
public class WrappedTest<K, V> implements Iterable<Map.Entry<K, V>>,
Iterable2<Map.Entry<K, V>> {
private static class En<Ke, Va> implements Map.Entry<Ke, Va> {
public Ke getKey() {
return null;
}
public Va getValue() {
return null;
}
public Va setValue( Va value ) {
return null;
}
}
private Set<En<K, V>> set = new HashSet<En<K, V>>();
// works but not usable:
// private Set<Map.Entry<K, V>> set = new HashSet<Map.Entry<K,
V>>();
public Iterator<Map.Entry<K, V>> iterator() {
// error in this line:
return set.iterator();
}
// this is ok
public Iterator<? extends Entry<K, V>> iter() {
return set.iterator();
}
// works but inheritance from Iterable<Map.Entry<K, V>> fails:
// public Iterator<? extends Map.Entry<K, V>> iterator() {
// return set.iterator();
// }
}
package generics;
import java.util.Iterator;
public interface Iterable2<T> {
public Iterator<? extends T> iter();
}
Thomas Hawtin - 16 Oct 2006 17:15 GMT
> I have a similar situation as demonstrated below. I cannot find a
> proper solution to make method iterator() work properly. It works with
> the custom interface Iterable2 (see below). I tried several
> alternatives I could think of but to no avail (see comments in code).
> Any other ideas? Or am I running into a limitation of Iterable?
> Research did not turn up much useful information for this situation.
So you have an Iterator<D> but want to return it as type Iterator<B>,
where D extends B?
I suggest you write a proxy:
class IteratorTypeProxy<E> implements Iterator<E> {
private final Iterator<? extends E> target;
public static <E> Iterator<E> create(Iterator<? extends E> target) {
return new IteratorTypeProxy<E>(target);
}
private IteratorTypeProxy(Iterator<? extends E> target) {
if (target == null) {
throw new NullPointerException();
}
this.target = target;
}
public boolean hasNext() {
return target.hasNext();
}
public E next() {
return target.next();
}
public void remove() {
target.hasNext();
}
}
Note, you can't implement, say, the full ListIterator interface this
way. add(E) and set(E) wouldn't work.
As Iterable<B>.iterator gives an Iterator<B> instead of Iterator<?
extends B>, the method can be overridden to return ListIterator<B>. (It
also helps to make client code easier to read - as a rule, don't return
wildcarded types.)
Tom Hawtin
Robert Klemme - 16 Oct 2006 19:50 GMT
>> I have a similar situation as demonstrated below. I cannot find a
>> proper solution to make method iterator() work properly. It works
[quoted text clipped - 5 lines]
> So you have an Iterator<D> but want to return it as type Iterator<B>,
> where D extends B?
Exactly.
> I suggest you write a proxy:
<snip/>
I have considered that myself but would obviously prefer to not have to
do that as I know the instances returned from the iterator are
compatible. It just does not feel right so I thought I'd first check
whether I overlooked some generics wizardry. But I assume there is no
such thing and there is probably a good reason that interface Iterable
returns an Iterator<T> and also that you cannot implement an interface
with a wildcard. If anyone can offer insights as to why that is I'd be
glad to learn.
> As Iterable<B>.iterator gives an Iterator<B> instead of Iterator<?
> extends B>, the method can be overridden to return ListIterator<B>. (It
> also helps to make client code easier to read - as a rule, don't return
> wildcarded types.)
Thanks!
Kind regards
robert