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.