Reputation: 4720
I am making a class that maps Strings to Integers. I want to be able to get the Integer associated with a particular String and iterate through the entries, which are defined as another class that implements Map.Entry<String, Integer>
.
Currently I have this:
public class MyMap implements Iterable<MyEntry> {
private final Map<String, Integer> wrappedMap =
new HashMap<String, Integer>();
@Override
public Iterator<MyEntry> iterator() {
return wrappedMap.entrySet().iterator();
}
//more methods
}
It's not compiling because of a type mismatch even though MyEntry implements Map.Entry<String, Integer>
.
Is there a way to make a custom implementation of Map.Entry? Is there an easier way to do this that I'm overlooking? Thanks in advanced!
Upvotes: 0
Views: 1499
Reputation: 4519
Why not use just a regular map?
Map<String, MyEntry> map = new HashMap<String, MyEntry>();
Then you iterator will be simply this:
Iterator<MyEntry> iter = map.values().iterator();
Upvotes: 2
Reputation: 3175
It's not compiling because MyEntry is not a part of the hashmap at all. If you want to return a list of MyEntry then you need to copy the data elements into a MyEntry instance and load that into a collection. Which is going to be slow and consume a considerable amount of memory.
It should be:
@Override
public Iterator<Map.Entry<String,Integer>> iterator() {
return wrappedMap.entrySet().iterator();
}
The call to entrySet()
returns a Set which contains the mappings in the hashmap. So the iterator needs to iterate over Entry
objects
Upvotes: 2
Reputation: 92147
Even though MyEntry
implements Map.Entry<K,V>
, it is not the case that an Iterator<MyEntry>
implements Iterator<Map.Entry<K,V>>
. For a class like Iterator
, that distinction doesn't make intuitive sense to a human being, so let's instead think of a Box<E>
class, which has .put(E)
and .contains(E)
methods. Is a Box<Dinosaur>
a subclass of Box<Animal>
? You might think so, but that's not the case: in a Box<Animal>
it's legal to call .put(someMammal)
, but in a Box<Dinosaur>
that is clearly illegal. Since Box<Dinosaur>
can't support all actions that are legal on a Box<Animal>
, it is definitely not a subclass and cannot be substituted in at will.
From the compiler's point of view, the same concern might apply to iterators, and so you can't overload .iterator()
to return an object which is not an instance of Iterator<K,V>
.
Upvotes: 1