--- jsr166/src/main/java/util/AbstractMap.java 2005/04/18 05:18:29 1.6 +++ jsr166/src/main/java/util/AbstractMap.java 2005/06/24 20:44:49 1.15 @@ -6,37 +6,41 @@ */ package java.util; +import java.util.*; // for javadoc (till 6280605 is fixed) import java.util.Map.Entry; /** * This class provides a skeletal implementation of the Map - * interface, to minimize the effort required to implement this interface.

+ * interface, to minimize the effort required to implement this interface. * - * To implement an unmodifiable map, the programmer needs only to extend this + *

To implement an unmodifiable map, the programmer needs only to extend this * class and provide an implementation for the entrySet method, which * returns a set-view of the map's mappings. Typically, the returned set * will, in turn, be implemented atop AbstractSet. This set should * not support the add or remove methods, and its iterator - * should not support the remove method.

+ * should not support the remove method. * - * To implement a modifiable map, the programmer must additionally override + *

To implement a modifiable map, the programmer must additionally override * this class's put method (which otherwise throws an * UnsupportedOperationException), and the iterator returned by * entrySet().iterator() must additionally implement its - * remove method.

+ * remove method. * - * The programmer should generally provide a void (no argument) and map + *

The programmer should generally provide a void (no argument) and map * constructor, as per the recommendation in the Map interface - * specification.

+ * specification. * - * The documentation for each non-abstract methods in this class describes its + *

The documentation for each non-abstract methods in this class describes its * implementation in detail. Each of these methods may be overridden if the - * map being implemented admits a more efficient implementation.

+ * map being implemented admits a more efficient implementation. * - * This class is a member of the + *

This class is a member of the * * Java Collections Framework. * + * @param the type of keys maintained by this map + * @param the type of mapped values + * * @author Josh Bloch * @author Neal Gafter * @version %I%, %G% @@ -56,45 +60,34 @@ public abstract class AbstractMap i // Query Operations /** - * Returns the number of key-value mappings in this map. If the map - * contains more than Integer.MAX_VALUE elements, returns - * Integer.MAX_VALUE.

- * - * This implementation returns entrySet().size(). + * {@inheritDoc} * - * @return the number of key-value mappings in this map. + *

This implementation returns entrySet().size(). */ public int size() { return entrySet().size(); } /** - * Returns true if this map contains no key-value mappings.

- * - * This implementation returns size() == 0. + * {@inheritDoc} * - * @return true if this map contains no key-value mappings. + *

This implementation returns size() == 0. */ public boolean isEmpty() { return size() == 0; } /** - * Returns true if this map maps one or more keys to this value. - * More formally, returns true if and only if this map contains - * at least one mapping to a value v such that (value==null ? - * v==null : value.equals(v)). This operation will probably require - * time linear in the map size for most implementations of map.

- * - * This implementation iterates over entrySet() searching for an entry - * with the specified value. If such an entry is found, true is - * returned. If the iteration terminates without finding such an entry, - * false is returned. Note that this implementation requires - * linear time in the size of the map. - * - * @param value value whose presence in this map is to be tested. - * - * @return true if this map maps one or more keys to this value. + * {@inheritDoc} + * + *

This implementation iterates over entrySet() searching + * for an entry with the specified value. If such an entry is found, + * true is returned. If the iteration terminates without + * finding such an entry, false is returned. Note that this + * implementation requires linear time in the size of the map. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} */ public boolean containsValue(Object value) { Iterator> i = entrySet().iterator(); @@ -115,22 +108,17 @@ public abstract class AbstractMap i } /** - * Returns true if this map contains a mapping for the specified - * key.

+ * {@inheritDoc} * - * This implementation iterates over entrySet() searching for an - * entry with the specified key. If such an entry is found, true - * is returned. If the iteration terminates without finding such an - * entry, false is returned. Note that this implementation - * requires linear time in the size of the map; many implementations will - * override this method. - * - * @param key key whose presence in this map is to be tested. - * @return true if this map contains a mapping for the specified - * key. - * - * @throws NullPointerException if the key is null and this map - * does not permit null keys. + *

This implementation iterates over entrySet() searching + * for an entry with the specified key. If such an entry is found, + * true is returned. If the iteration terminates without + * finding such an entry, false is returned. Note that this + * implementation requires linear time in the size of the map; many + * implementations will override this method. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} */ public boolean containsKey(Object key) { Iterator> i = entrySet().iterator(); @@ -151,27 +139,17 @@ public abstract class AbstractMap i } /** - * Returns the value to which this map maps the specified key. Returns - * null if the map contains no mapping for this key. A return - * value of null does not necessarily indicate that the - * map contains no mapping for the key; it's also possible that the map - * explicitly maps the key to null. The containsKey operation - * may be used to distinguish these two cases.

- * - * This implementation iterates over entrySet() searching for an - * entry with the specified key. If such an entry is found, the entry's - * value is returned. If the iteration terminates without finding such an - * entry, null is returned. Note that this implementation - * requires linear time in the size of the map; many implementations will - * override this method. - * - * @param key key whose associated value is to be returned. - * @return the value to which this map maps the specified key. - * - * @throws NullPointerException if the key is null and this map - * does not permit null keys. - * - * @see #containsKey(Object) + * {@inheritDoc} + * + *

This implementation iterates over entrySet() searching + * for an entry with the specified key. If such an entry is found, + * the entry's value is returned. If the iteration terminates without + * finding such an entry, null is returned. Note that this + * implementation requires linear time in the size of the map; many + * implementations will override this method. + * + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} */ public V get(Object key) { Iterator> i = entrySet().iterator(); @@ -195,65 +173,40 @@ public abstract class AbstractMap i // Modification Operations /** - * Associates the specified value with the specified key in this map - * (optional operation). If the map previously contained a mapping for - * this key, the old value is replaced.

+ * {@inheritDoc} * - * This implementation always throws an + *

This implementation always throws an * UnsupportedOperationException. * - * @param key key with which the specified value is to be associated. - * @param value value to be associated with the specified key. - * - * @return the previous value associated with specified key, or null - * if there was no mapping for key. (A null return can - * also indicate that the map previously associated null - * with the specified key, if the implementation supports - * null values.) - * - * @throws UnsupportedOperationException if the put operation is - * not supported by this map. - * - * @throws ClassCastException if the class of the specified key or value - * prevents it from being stored in this map. - * - * @throws IllegalArgumentException if some aspect of this key or value * - * prevents it from being stored in this map. - * - * @throws NullPointerException if this map does not permit null - * keys or values, and the specified key or value is - * null. + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} */ public V put(K key, V value) { throw new UnsupportedOperationException(); } /** - * Removes the mapping for this key from this map if present (optional - * operation).

+ * {@inheritDoc} * - * This implementation iterates over entrySet() searching for an + *

This implementation iterates over entrySet() searching for an * entry with the specified key. If such an entry is found, its value is * obtained with its getValue operation, the entry is removed - * from the Collection (and the backing map) with the iterator's + * from the collection (and the backing map) with the iterator's * remove operation, and the saved value is returned. If the * iteration terminates without finding such an entry, null is * returned. Note that this implementation requires linear time in the - * size of the map; many implementations will override this method.

+ * size of the map; many implementations will override this method. + * + *

Note that this implementation throws an + * UnsupportedOperationException if the entrySet + * iterator does not support the remove method and this map + * contains a mapping for the specified key. * - * Note that this implementation throws an - * UnsupportedOperationException if the entrySet iterator - * does not support the remove method and this map contains a - * mapping for the specified key. - * - * @param key key whose mapping is to be removed from the map. - * @return the previous value associated with specified key, or null - * if there was no entry for key. (A null return can - * also indicate that the map previously associated null - * with the specified key, if the implementation supports - * null values.) - * @throws UnsupportedOperationException if the remove operation - * is not supported by this map. + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} */ public V remove(Object key) { Iterator> i = entrySet().iterator(); @@ -284,34 +237,23 @@ public abstract class AbstractMap i // Bulk Operations /** - * Copies all of the mappings from the specified map to this map - * (optional operation). These mappings will replace any mappings that - * this map had for any of the keys currently in the specified map.

+ * {@inheritDoc} * - * This implementation iterates over the specified map's + *

This implementation iterates over the specified map's * entrySet() collection, and calls this map's put - * operation once for each entry returned by the iteration.

+ * operation once for each entry returned by the iteration. * - * Note that this implementation throws an + *

Note that this implementation throws an * UnsupportedOperationException if this map does not support * the put operation and the specified map is nonempty. * - * @param t mappings to be stored in this map. - * - * @throws UnsupportedOperationException if the putAll operation - * is not supported by this map. - * - * @throws ClassCastException if the class of a key or value in the - * specified map prevents it from being stored in this map. - * - * @throws IllegalArgumentException if some aspect of a key or value in - * the specified map prevents it from being stored in this map. - * @throws NullPointerException if the specified map is null, or if - * this map does not permit null keys or values, and the - * specified map contains null keys or values. + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} */ - public void putAll(Map t) { - Iterator> i = t.entrySet().iterator(); + public void putAll(Map m) { + Iterator> i = m.entrySet().iterator(); while (i.hasNext()) { Entry e = i.next(); put(e.getKey(), e.getValue()); @@ -319,16 +261,15 @@ public abstract class AbstractMap i } /** - * Removes all mappings from this map (optional operation).

+ * {@inheritDoc} * - * This implementation calls entrySet().clear(). + *

This implementation calls entrySet().clear(). * - * Note that this implementation throws an + *

Note that this implementation throws an * UnsupportedOperationException if the entrySet * does not support the clear operation. * - * @throws UnsupportedOperationException clear is not supported - * by this map. + * @throws UnsupportedOperationException {@inheritDoc} */ public void clear() { entrySet().clear(); @@ -346,27 +287,19 @@ public abstract class AbstractMap i transient volatile Collection values = null; /** - * Returns a Set view of the keys contained in this map. The Set is - * backed by the map, so changes to the map are reflected in the Set, - * and vice-versa. (If the map is modified while an iteration over - * the Set is in progress, the results of the iteration are undefined.) - * The Set supports element removal, which removes the corresponding entry - * from the map, via the Iterator.remove, Set.remove, removeAll - * retainAll, and clear operations. It does not support the add or - * addAll operations.

- * - * This implementation returns a Set that subclasses - * AbstractSet. The subclass's iterator method returns a "wrapper - * object" over this map's entrySet() iterator. The size method delegates - * to this map's size method and the contains method delegates to this - * map's containsKey method.

+ * {@inheritDoc} * - * The Set is created the first time this method is called, + *

This implementation returns a set that subclasses {@link AbstractSet}. + * The subclass's iterator method returns a "wrapper object" over this + * map's entrySet() iterator. The size method + * delegates to this map's size method and the + * contains method delegates to this map's + * containsKey method. + * + *

The set is created the first time this method is called, * and returned in response to all subsequent calls. No synchronization * is performed, so there is a slight chance that multiple calls to this - * method will not all return the same Set. - * - * @return a Set view of the keys contained in this map. + * method will not all return the same set. */ public Set keySet() { if (keySet == null) { @@ -402,28 +335,19 @@ public abstract class AbstractMap i } /** - * Returns a collection view of the values contained in this map. The - * collection is backed by the map, so changes to the map are reflected in - * the collection, and vice-versa. (If the map is modified while an - * iteration over the collection is in progress, the results of the - * iteration are undefined.) The collection supports element removal, - * which removes the corresponding entry from the map, via the - * Iterator.remove, Collection.remove, - * removeAll, retainAll and clear operations. - * It does not support the add or addAll operations.

- * - * This implementation returns a collection that subclasses abstract - * collection. The subclass's iterator method returns a "wrapper object" - * over this map's entrySet() iterator. The size method - * delegates to this map's size method and the contains method delegates - * to this map's containsValue method.

+ * {@inheritDoc} + * + *

This implementation returns a collection that subclasses {@link + * AbstractCollection}. The subclass's iterator method returns a + * "wrapper object" over this map's entrySet() iterator. + * The size method delegates to this map's size + * method and the contains method delegates to this map's + * containsValue method. * - * The collection is created the first time this method is called, and + *

The collection is created the first time this method is called, and * returned in response to all subsequent calls. No synchronization is * performed, so there is a slight chance that multiple calls to this - * method will not all return the same Collection. - * - * @return a collection view of the values contained in this map. + * method will not all return the same collection. */ public Collection values() { if (values == null) { @@ -458,19 +382,6 @@ public abstract class AbstractMap i return values; } - /** - * Returns a set view of the mappings contained in this map. Each element - * in this set is a Map.Entry. The set is backed by the map, so changes - * to the map are reflected in the set, and vice-versa. (If the map is - * modified while an iteration over the set is in progress, the results of - * the iteration are undefined.) The set supports element removal, which - * removes the corresponding entry from the map, via the - * Iterator.remove, Set.remove, removeAll, - * retainAll and clear operations. It does not support - * the add or addAll operations. - * - * @return a set view of the mappings contained in this map. - */ public abstract Set> entrySet(); @@ -479,25 +390,23 @@ public abstract class AbstractMap i /** * Compares the specified object with this map for equality. Returns * true if the given object is also a map and the two maps - * represent the same mappings. More formally, two maps t1 and - * t2 represent the same mappings if - * t1.keySet().equals(t2.keySet()) and for every key k - * in t1.keySet(), (t1.get(k)==null ? t2.get(k)==null : - * t1.get(k).equals(t2.get(k))) . This ensures that the + * represent the same mappings. More formally, two maps m1 and + * m2 represent the same mappings if + * m1.entrySet().equals(m2.entrySet()). This ensures that the * equals method works properly across different implementations - * of the map interface.

+ * of the Map interface. * - * This implementation first checks if the specified object is this map; + *

This implementation first checks if the specified object is this map; * if so it returns true. Then, it checks if the specified - * object is a map whose size is identical to the size of this set; if + * object is a map whose size is identical to the size of this map; if * not, it returns false. If so, it iterates over this map's * entrySet collection, and checks that the specified map * contains each mapping that this map contains. If the specified map * fails to contain such a mapping, false is returned. If the * iteration completes, true is returned. * - * @param o object to be compared for equality with this map. - * @return true if the specified object is equal to this map. + * @param o object to be compared for equality with this map + * @return true if the specified object is equal to this map */ public boolean equals(Object o) { if (o == this) @@ -505,8 +414,8 @@ public abstract class AbstractMap i if (!(o instanceof Map)) return false; - Map t = (Map) o; - if (t.size() != size()) + Map m = (Map) o; + if (m.size() != size()) return false; try { @@ -516,16 +425,16 @@ public abstract class AbstractMap i K key = e.getKey(); V value = e.getValue(); if (value == null) { - if (!(t.get(key)==null && t.containsKey(key))) + if (!(m.get(key)==null && m.containsKey(key))) return false; } else { - if (!value.equals(t.get(key))) + if (!value.equals(m.get(key))) return false; } } - } catch(ClassCastException unused) { + } catch (ClassCastException unused) { return false; - } catch(NullPointerException unused) { + } catch (NullPointerException unused) { return false; } @@ -535,18 +444,17 @@ public abstract class AbstractMap i /** * Returns the hash code value for this map. The hash code of a map is * defined to be the sum of the hash codes of each entry in the map's - * entrySet() view. This ensures that t1.equals(t2) - * implies that t1.hashCode()==t2.hashCode() for any two maps - * t1 and t2, as required by the general contract of - * Object.hashCode.

- * - * This implementation iterates over entrySet(), calling - * hashCode on each element (entry) in the Collection, and adding - * up the results. + * entrySet() view. This ensures that m1.equals(m2) + * implies that m1.hashCode()==m2.hashCode() for any two maps + * m1 and m2, as required by the general contract of + * {@link Object#hashCode}. + * + *

This implementation iterates over entrySet(), calling + * {@link Map.Entry#hashCode hashCode()} on each element (entry) in the + * set, and adding up the results. * - * @return the hash code value for this map. + * @return the hash code value for this map * @see Map.Entry#hashCode() - * @see Object#hashCode() * @see Object#equals(Object) * @see Set#equals(Object) */ @@ -575,11 +483,11 @@ public abstract class AbstractMap i * appended. Finally a right brace is appended. A string is obtained * from the stringbuffer, and returned. * - * @return a String representation of this map. + * @return a String representation of this map */ public String toString() { - StringBuffer buf = new StringBuffer(); - buf.append("{"); + StringBuilder sb = new StringBuilder(); + sb.append("{"); Iterator> i = entrySet().iterator(); boolean hasNext = i.hasNext(); @@ -588,28 +496,28 @@ public abstract class AbstractMap i K key = e.getKey(); V value = e.getValue(); if (key == this) - buf.append("(this Map)"); + sb.append("(this Map)"); else - buf.append(key); - buf.append("="); + sb.append(key); + sb.append("="); if (value == this) - buf.append("(this Map)"); + sb.append("(this Map)"); else - buf.append(value); + sb.append(value); hasNext = i.hasNext(); if (hasNext) - buf.append(", "); + sb.append(", "); } - buf.append("}"); - return buf.toString(); + sb.append("}"); + return sb.toString(); } - + /** * Returns a shallow copy of this AbstractMap instance: the keys * and values themselves are not cloned. * - * @return a shallow copy of this map. + * @return a shallow copy of this map */ protected Object clone() throws CloneNotSupportedException { AbstractMap result = (AbstractMap)super.clone(); @@ -641,6 +549,8 @@ public abstract class AbstractMap i * implementations. For example, it may be convenient to return * arrays of SimpleEntry instances in method * Map.entrySet().toArray + * + * @since 1.6 */ public static class SimpleEntry implements Entry { private final K key; @@ -662,7 +572,7 @@ public abstract class AbstractMap i * Creates an entry representing the same mapping as the * specified entry. * - * @param entry the entry to copy. + * @param entry the entry to copy */ public SimpleEntry(Entry entry) { this.key = entry.getKey(); @@ -672,7 +582,7 @@ public abstract class AbstractMap i /** * Returns the key corresponding to this entry. * - * @return the key corresponding to this entry. + * @return the key corresponding to this entry */ public K getKey() { return key; @@ -681,7 +591,7 @@ public abstract class AbstractMap i /** * Returns the value corresponding to this entry. * - * @return the value corresponding to this entry. + * @return the value corresponding to this entry */ public V getValue() { return value; @@ -691,8 +601,8 @@ public abstract class AbstractMap i * Replaces the value corresponding to this entry with the specified * value. * - * @param value new value to be stored in this entry. - * @return the old value corresponding to the entry. + * @param value new value to be stored in this entry + * @return the old value corresponding to the entry */ public V setValue(V value) { V oldValue = this.value; @@ -718,7 +628,7 @@ public abstract class AbstractMap i * entry's key followed by the equals character ("=") * followed by the string representation of this entry's value. * - * @return a String representation of this map entry. + * @return a String representation of this map entry */ public String toString() { return key + "=" + value; @@ -731,6 +641,8 @@ public abstract class AbstractMap i * does not support method setValue. This class may be * convenient in methods that return thread-safe snapshots of * key-value mappings. + * + * @since 1.6 */ public static class SimpleImmutableEntry implements Entry { private final K key; @@ -752,7 +664,7 @@ public abstract class AbstractMap i * Creates an entry representing the same mapping as the * specified entry. * - * @param entry the entry to copy. + * @param entry the entry to copy */ public SimpleImmutableEntry(Entry entry) { this.key = entry.getKey(); @@ -762,7 +674,7 @@ public abstract class AbstractMap i /** * Returns the key corresponding to this entry. * - * @return the key corresponding to this entry. + * @return the key corresponding to this entry */ public K getKey() { return key; @@ -771,7 +683,7 @@ public abstract class AbstractMap i /** * Returns the value corresponding to this entry. * - * @return the value corresponding to this entry. + * @return the value corresponding to this entry */ public V getValue() { return value; @@ -783,7 +695,7 @@ public abstract class AbstractMap i * UnsupportedOperationException, as this class implements * an immutable map entry. * - * @param value new value to be stored in this entry. + * @param value new value to be stored in this entry * @return (Does not return) * @throws UnsupportedOperationException always */ @@ -809,7 +721,7 @@ public abstract class AbstractMap i * entry's key followed by the equals character ("=") * followed by the string representation of this entry's value. * - * @return a String representation of this map entry. + * @return a String representation of this map entry */ public String toString() { return key + "=" + value;