下面是
Java Collections source中该方法的实现.实际上,该方法返回AbstractSet的子类,其中包含Map以及瞬态Set.
/**
* Returns a set backed by the specified map. The resulting set displays
* the same ordering, concurrency, and performance characteristics as the
* backing map. In essence, this factory method provides a {@link Set}
* implementation corresponding to any {@link Map} implementation. There
* is no need to use this method on a {@link Map} implementation that
* already has a corresponding {@link Set} implementation (such as {@link
* HashMap} or {@link TreeMap}).
*
*
Each method invocation on the set returned by this method results in
* exactly one method invocation on the backing map or its keySet
* view, with one exception. The addAll method is implemented
* as a sequence of put invocations on the backing map.
*
*
The specified map must be empty at the time this method is invoked,
* and should not be accessed directly after this method returns. These
* conditions are ensured if the map is created empty, passed directly
* to this method, and no reference to the map is retained, as illustrated
* in the following code fragment:
*
* Set<Object> weakHashSet = Collections.newSetFromMap(
* new WeakHashMap<Object, Boolean>());
*
*
* @param map the backing map
* @return the set backed by the map
* @throws IllegalArgumentException if map is not empty
* @since 1.6
*/
public static Set newSetFromMap(Map map) {
return new SetFromMap(map);
}
private static class SetFromMap extends AbstractSet
implements Set, Serializable
{
private final Map m; // The backing map
private transient Set s; // Its keySet
SetFromMap(Map map) {
if (!map.isEmpty())
throw new IllegalArgumentException("Map is non-empty");
m = map;
s = map.keySet();
}
public void clear() { m.clear(); }
public int size() { return m.size(); }
public boolean isEmpty() { return m.isEmpty(); }
public boolean contains(Object o) { return m.containsKey(o); }
public boolean remove(Object o) { return m.remove(o) != null; }
public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
public Iterator iterator() { return s.iterator(); }
public Object[] toArray() { return s.toArray(); }
public T[] toArray(T[] a) { return s.toArray(a); }
public String toString() { return s.toString(); }
public int hashCode() { return s.hashCode(); }
public boolean equals(Object o) { return o == this || s.equals(o); }
public boolean containsAll(Collection> c) {return s.containsAll(c);}
public boolean removeAll(Collection> c) {return s.removeAll(c);}
public boolean retainAll(Collection> c) {return s.retainAll(c);}
// addAll is the only inherited implementation
private static final long serialVersionUID = 2454657854757543876L;
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException
{
stream.defaultReadObject();
s = m.keySet();
}
}