The source code of HashMap.values()
is shown as follows
public Collection values() {
Collection vs = values;
return (vs !=
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> 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]"