You're actually asking two different questions:
- Does a
HashMap
use a HashSet
to store its keys?
- Does
HashMap.keySet()
return a HashSet
?
The answer to both questions is no, and for the same reason, but there's no technical reason preventing either 1. or 2. from being true.
A HashSet
is actually a wrapper around a HashMap
; HashSet
has the following member variable:
private transient HashMap<E,Object> map;
It populates a PRESENT
sentinel value as the value of the map when an object is added to the set.
Now a HashMap
stores it's data in an array of Entry
objects holding the Key, Value pairs:
transient Entry<K,V>[] table;
And it's keySet()
method returns an instance of the inner class KeySet
:
public Set<K> keySet() {
Set<K> ks = keySet;
return (ks != null ? ks : (keySet = new KeySet()));
}
private final class KeySet extends AbstractSet<K> {
// minimal Set implementation to access the keys of the map
}
Since KeySet
is a private inner class, as far as you should be concerned it is simply an arbitrary Set
implementation.
Like I said, there's no reason this has to be the case. You could absolutely implement a Map
class that used a HashSet
internally, and then have your Map
return a HashSet
from .keySet()
. However this would be inefficient and difficult to code; the existing implementation is both more robust and more efficient than naive Map
/Set
implementations.
Code snippets taken from Oracle JDK 1.7.0_17. You can view the source of your version of Java inside the src.zip
file in your Java install directory.