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?
The Java HashMap keySet() method returns a set view of all the keys present in entries of the 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.
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.
The Java HashMap values() method returns a view of all the values present in entries of the hashmap.
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]"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With