cs-dev
cs-dev

Reputation: 107

not able to understand entrySet() method

We can use an entrySet() method to iterate over the hashmap key-value pairs stored in Node[] table field .

HahMap<K,V> hashmap = new HashMap<>() ;

public Set<Map.Entry<K,V>> entrySet() 
{
    Set<Map.Entry<K,V>> es;
    return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}

When we use this in a for-each loop like :

for ( Map.Entry<K,V> entry : hashmap.entrySet () ) 
{
... 
// entry is an object of return type Map.Entry and object type Node . 
// got the object type by calling entry.getClass() and also no other inner class other than Node implements Map.Entry .   ; 

} 

These objects are stored in a Set . But where is the code which links them to the field table which has key-value pairs .

For example : In toString() method when we get Iterable using iterator() method , and call next() method on Iterable the call goes to nextNode() of HashIterator class where the object returned is linked to table field of HashMap class . But what happens here ? Please help .

Upvotes: 1

Views: 1919

Answers (2)

Holger
Holger

Reputation: 298143

You seem to lack the understanding of what a view is. A view has no stored data, but just fulfills a certain interface by delegating to the actual data object.

A simple example is the list view created via Collections.unmodifiableList(…) which does not contain any data, but delegates all method calls to the original list, excluding the modification methods, of course.

The entry set fulfills the Set interface by delegating to the underlying map. Most notably, by returning an Iterator, as most methods are build upon this, only a few others are overridden for performance, e.g. size() delegates directly to the map’s size(). So if it appears as if the entry set contains something, it is, because the iterator reports it during the traversal.

The Hashmap’s entry set iterator iterates over the internal array of entries, just like the key set iterator and the value collection iterator. The only difference between them is which object they return in the next() method, the entry set iterator just returns the entry, the other two extract the key resp. value of the entry. That’s why these iterator only override that single method.

Note that this interaction can also be seen the other way round. When you implement a Map by extending AbstractMap, the entrySet() is the only method you need to implement, all other map methods are already implemented via delegation to the entry set. You might override some of them for performance, though. But the question, which actually contains the data, is moot, both, the Map and the entry Set are views to the same underlying data.

Maybe the following example helps:

String[][] pairs={ {"foo","bar"}, {"hello","world"} };

Map<String,String> map = new AbstractMap<String, String>() {
    public Set<Map.Entry<String, String>> entrySet() {
        return new AbstractSet<Entry<String, String>>() {
            public Iterator<Map.Entry<String, String>> iterator() {
                return Arrays.stream(pairs)
                    .<Entry<String,String>>map(p -> new SimpleImmutableEntry<>(p[0],p[1]))
                    .iterator();
            }
            public int size() {
                return pairs.length;
            }
        };
    }
};

System.out.println(map.get("foo"));
System.out.println(map.containsKey("hello"));
System.out.println(map.containsValue("world"));
map.forEach((k,v) -> System.out.println(k+" -> "+v));
System.out.println(map);

It creates an immutable map that is never put into. Still, it reports the intended contents through all Map methods, just because the entry set iterator reports this content.

Upvotes: 2

Eugene
Eugene

Reputation: 120848

If I have not missed anything from your question: EntrySet overrides iterator method (making it an Iterable to be used in forEach) that in turn returns an EntryIterator - it overrides the next method:

public final Map.Entry<K,V> next() { return nextNode(); }

But it also extends HashIterator that defines the hasNext method.

It is actually as simple as that. But generally these are inner classes - and they have access to everything they might need in the HashMap class.

Upvotes: 0

Related Questions