Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do HashMap.values() and HashMap.keySet() return values and keys?

Tags:

java

hashmap

The source code of HashMap.values() is shown as follows

public Collection<V> values() {
    Collection<V> vs = values;
    return (vs != null ? vs : (values = new Values()));
}

As you can see, when the values() method first called, it just returns a Values object. The Values object is a subclass of AbstractCollection with no constructor, and of course contains no element. But when I called the method, it returned a collection rapidly

Collection<String> values = map.values();
System.out.println(values);

That's so weird. Not only values(), but also keySet() and entrySet() method return such empty objects. So, here is my question, when and how do these methods return objects with elements we need?

like image 460
Yohn Avatar asked Jun 08 '15 11:06

Yohn


People also ask

What does HashMap keySet return?

The Java HashMap keySet() method returns a set view of all the keys present in entries of the hashmap.

How will you retrieve values and keys from HashMap?

get() method of HashMap class is used to retrieve or fetch the value mapped by a particular key mentioned in the parameter. It returns NULL when the map contains no such mapping for the key.

How does HashMap keySet work?

HashMap. keySet() method in Java is used to create a set out of the key elements contained in the hash map. It basically returns a set view of the keys or we can create a new set and store the key elements in them.

What does values return from HashMap?

The Java HashMap values() method returns a view of all the values present in entries of the hashmap.


1 Answers

It's a misconception that the Values class is "of course empty". Just because there is no method called on it and its constructor doesn't have any arguments doesn't mean that the collection is empty.

The Values class is an "inner class" (a non-static nested class) of HashMap, which means that it has an implicit reference to the HashMap object that created it. It can therefore access all elements of the HashMap, either explicitly by using the HashMap.this reference or by just accessing the members directly. Since it is an inner class, it is even allowed to access the HashMap's private members.

You can see that for example in the Values class' implementation of the size method:

public int size() {
    return size;
}

The Values class doesn't have a size member, so that size refers to the HashMap's size. It's equivalent to:

public int size() {
    return HashMap.this.size;
}

EDIT: Note that this also means that the collection you receive is not a copy, but still refers to the original HashMap contents and therefore changes when you update the HashMap:

    // Getting the entry set (not a copy!)
    Set<Entry<String, String>> entries = map.entrySet();

    // Add elements to the map afterwards
    map.put("abc", "def");

    // Check out the entries in the collection
    // (magically containing the elements added after getting the collection)
    System.out.println(entries); // "[abc=def]"
like image 92
mastov Avatar answered Oct 19 '22 07:10

mastov