ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/AbstractMap.java
(Generate patch)

Comparing jsr166/src/main/java/util/AbstractMap.java (file contents):
Revision 1.11 by jsr166, Tue May 17 04:03:50 2005 UTC vs.
Revision 1.19 by jsr166, Mon Dec 5 02:56:59 2005 UTC

# Line 1 | Line 1
1   /*
2   * %W% %E%
3   *
4 < * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
4 > * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5   * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6   */
7  
8   package java.util;
9 + import java.util.*; // for javadoc (till 6280605 is fixed)
10   import java.util.Map.Entry;
11  
12   /**
# Line 252 | Line 253 | public abstract class AbstractMap<K,V> i
253       * @throws IllegalArgumentException      {@inheritDoc}
254       */
255      public void putAll(Map<? extends K, ? extends V> m) {
256 <        Iterator<? extends Entry<? extends K, ? extends V>> i = m.entrySet().iterator();
257 <        while (i.hasNext()) {
257 <            Entry<? extends K, ? extends V> e = i.next();
258 <            put(e.getKey(), e.getValue());
259 <        }
256 >        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
257 >            put(e.getKey(), e.getValue());
258      }
259  
260      /**
# Line 387 | Line 385 | public abstract class AbstractMap<K,V> i
385      // Comparison and hashing
386  
387      /**
388 <     * {@inheritDoc}
388 >     * Compares the specified object with this map for equality.  Returns
389 >     * <tt>true</tt> if the given object is also a map and the two maps
390 >     * represent the same mappings.  More formally, two maps <tt>m1</tt> and
391 >     * <tt>m2</tt> represent the same mappings if
392 >     * <tt>m1.entrySet().equals(m2.entrySet())</tt>.  This ensures that the
393 >     * <tt>equals</tt> method works properly across different implementations
394 >     * of the <tt>Map</tt> interface.
395       *
396       * <p>This implementation first checks if the specified object is this map;
397       * if so it returns <tt>true</tt>.  Then, it checks if the specified
# Line 397 | Line 401 | public abstract class AbstractMap<K,V> i
401       * contains each mapping that this map contains.  If the specified map
402       * fails to contain such a mapping, <tt>false</tt> is returned.  If the
403       * iteration completes, <tt>true</tt> is returned.
404 +     *
405 +     * @param o object to be compared for equality with this map
406 +     * @return <tt>true</tt> if the specified object is equal to this map
407       */
408      public boolean equals(Object o) {
409          if (o == this)
# Line 404 | Line 411 | public abstract class AbstractMap<K,V> i
411  
412          if (!(o instanceof Map))
413              return false;
414 <        Map<K,V> t = (Map<K,V>) o;
415 <        if (t.size() != size())
414 >        Map<K,V> m = (Map<K,V>) o;
415 >        if (m.size() != size())
416              return false;
417  
418          try {
# Line 415 | Line 422 | public abstract class AbstractMap<K,V> i
422                  K key = e.getKey();
423                  V value = e.getValue();
424                  if (value == null) {
425 <                    if (!(t.get(key)==null && t.containsKey(key)))
425 >                    if (!(m.get(key)==null && m.containsKey(key)))
426                          return false;
427                  } else {
428 <                    if (!value.equals(t.get(key)))
428 >                    if (!value.equals(m.get(key)))
429                          return false;
430                  }
431              }
# Line 432 | Line 439 | public abstract class AbstractMap<K,V> i
439      }
440  
441      /**
442 <     * {@inheritDoc}
442 >     * Returns the hash code value for this map.  The hash code of a map is
443 >     * defined to be the sum of the hash codes of each entry in the map's
444 >     * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt>
445 >     * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps
446 >     * <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of
447 >     * {@link Object#hashCode}.
448       *
449       * <p>This implementation iterates over <tt>entrySet()</tt>, calling
450 <     * <tt>hashCode()</tt> on each element (entry) in the set, and
451 <     * adding up the results.
450 >     * {@link Map.Entry#hashCode hashCode()} on each element (entry) in the
451 >     * set, and adding up the results.
452       *
453 +     * @return the hash code value for this map
454       * @see Map.Entry#hashCode()
442     * @see Object#hashCode()
455       * @see Object#equals(Object)
456       * @see Set#equals(Object)
457       */
# Line 459 | Line 471 | public abstract class AbstractMap<K,V> i
471       * <tt>", "</tt> (comma and space).  Each key-value mapping is rendered as
472       * the key followed by an equals sign (<tt>"="</tt>) followed by the
473       * associated value.  Keys and values are converted to strings as by
474 <     * <tt>String.valueOf(Object)</tt>.<p>
463 <     *
464 <     * This implementation creates an empty string buffer, appends a left
465 <     * brace, and iterates over the map's <tt>entrySet</tt> view, appending
466 <     * the string representation of each <tt>map.entry</tt> in turn.  After
467 <     * appending each entry except the last, the string <tt>", "</tt> is
468 <     * appended.  Finally a right brace is appended.  A string is obtained
469 <     * from the stringbuffer, and returned.
474 >     * {@link String#valueOf(Object)}.
475       *
476 <     * @return a String representation of this map
476 >     * @return a string representation of this map
477       */
478      public String toString() {
474        StringBuffer buf = new StringBuffer();
475        buf.append("{");
476
479          Iterator<Entry<K,V>> i = entrySet().iterator();
480 <        boolean hasNext = i.hasNext();
481 <        while (hasNext) {
480 >        if (! i.hasNext())
481 >            return "{}";
482 >
483 >        StringBuilder sb = new StringBuilder();
484 >        sb.append('{');
485 >        for (;;) {
486              Entry<K,V> e = i.next();
487              K key = e.getKey();
488 <            V value = e.getValue();
489 <            if (key == this)
490 <                buf.append("(this Map)");
491 <            else
492 <                buf.append(key);
493 <            buf.append("=");
494 <            if (value == this)
495 <                buf.append("(this Map)");
490 <            else
491 <                buf.append(value);
492 <            hasNext = i.hasNext();
493 <            if (hasNext)
494 <                buf.append(", ");
495 <        }
496 <
497 <        buf.append("}");
498 <        return buf.toString();
488 >            V value = e.getValue();
489 >            sb.append(key   == this ? "(this Map)" : key);
490 >            sb.append('=');
491 >            sb.append(value == this ? "(this Map)" : value);
492 >            if (! i.hasNext())
493 >                return sb.append('}').toString();
494 >            sb.append(", ");
495 >        }
496      }
497  
498      /**
# Line 516 | Line 513 | public abstract class AbstractMap<K,V> i
513       * Test for equality, checking for nulls.
514       */
515      private static boolean eq(Object o1, Object o2) {
516 <        return (o1 == null ? o2 == null : o1.equals(o2));
516 >        return o1 == null ? o2 == null : o1.equals(o2);
517      }
518  
519      // Implementation Note: SimpleEntry and SimpleImmutableEntry
# Line 533 | Line 530 | public abstract class AbstractMap<K,V> i
530       * facilitates the process of building custom map
531       * implementations. For example, it may be convenient to return
532       * arrays of <tt>SimpleEntry</tt> instances in method
533 <     * <tt>Map.entrySet().toArray</tt>
533 >     * <tt>Map.entrySet().toArray</tt>.
534 >     *
535 >     * @since 1.6
536       */
537 <    public static class SimpleEntry<K,V> implements Entry<K,V> {
537 >    public static class SimpleEntry<K,V>
538 >        implements Entry<K,V>, java.io.Serializable
539 >    {
540 >        private static final long serialVersionUID = -8499721149061103585L;
541 >
542          private final K key;
543          private V value;
544  
# Line 593 | Line 596 | public abstract class AbstractMap<K,V> i
596              return oldValue;
597          }
598  
599 +        /**
600 +         * Compares the specified object with this entry for equality.
601 +         * Returns {@code true} if the given object is also a map entry and
602 +         * the two entries represent the same mapping.  More formally, two
603 +         * entries {@code e1} and {@code e2} represent the same mapping
604 +         * if<pre>
605 +         *   (e1.getKey()==null ?
606 +         *    e2.getKey()==null :
607 +         *    e1.getKey().equals(e2.getKey()))
608 +         *   &amp;&amp;
609 +         *   (e1.getValue()==null ?
610 +         *    e2.getValue()==null :
611 +         *    e1.getValue().equals(e2.getValue()))</pre>
612 +         * This ensures that the {@code equals} method works properly across
613 +         * different implementations of the {@code Map.Entry} interface.
614 +         *
615 +         * @param o object to be compared for equality with this map entry
616 +         * @return {@code true} if the specified object is equal to this map
617 +         *         entry
618 +         * @see    #hashCode
619 +         */
620          public boolean equals(Object o) {
621              if (!(o instanceof Map.Entry))
622                  return false;
# Line 600 | Line 624 | public abstract class AbstractMap<K,V> i
624              return eq(key, e.getKey()) && eq(value, e.getValue());
625          }
626  
627 +        /**
628 +         * Returns the hash code value for this map entry.  The hash code
629 +         * of a map entry {@code e} is defined to be: <pre>
630 +         *   (e.getKey()==null   ? 0 : e.getKey().hashCode()) ^
631 +         *   (e.getValue()==null ? 0 : e.getValue().hashCode())</pre>
632 +         * This ensures that {@code e1.equals(e2)} implies that
633 +         * {@code e1.hashCode()==e2.hashCode()} for any two Entries
634 +         * {@code e1} and {@code e2}, as required by the general
635 +         * contract of {@link Object#hashCode}.
636 +         *
637 +         * @return the hash code value for this map entry
638 +         * @see    #equals
639 +         */
640          public int hashCode() {
641 <            return ((key   == null)   ? 0 :   key.hashCode()) ^
642 <                   ((value == null)   ? 0 : value.hashCode());
641 >            return (key   == null ? 0 :   key.hashCode()) ^
642 >                   (value == null ? 0 : value.hashCode());
643          }
644  
645          /**
# Line 620 | Line 657 | public abstract class AbstractMap<K,V> i
657      }
658  
659      /**
660 <     * An Entry maintaining an immutable key and value, This class
660 >     * An Entry maintaining an immutable key and value.  This class
661       * does not support method <tt>setValue</tt>.  This class may be
662       * convenient in methods that return thread-safe snapshots of
663       * key-value mappings.
664 +     *
665 +     * @since 1.6
666       */
667 <    public static class SimpleImmutableEntry<K,V> implements Entry<K,V> {
667 >    public static class SimpleImmutableEntry<K,V>
668 >        implements Entry<K,V>, java.io.Serializable
669 >    {
670 >        private static final long serialVersionUID = 7138329143949025153L;
671 >
672          private final K key;
673          private final V value;
674  
# Line 684 | Line 727 | public abstract class AbstractMap<K,V> i
727              throw new UnsupportedOperationException();
728          }
729  
730 +        /**
731 +         * Compares the specified object with this entry for equality.
732 +         * Returns {@code true} if the given object is also a map entry and
733 +         * the two entries represent the same mapping.  More formally, two
734 +         * entries {@code e1} and {@code e2} represent the same mapping
735 +         * if<pre>
736 +         *   (e1.getKey()==null ?
737 +         *    e2.getKey()==null :
738 +         *    e1.getKey().equals(e2.getKey()))
739 +         *   &amp;&amp;
740 +         *   (e1.getValue()==null ?
741 +         *    e2.getValue()==null :
742 +         *    e1.getValue().equals(e2.getValue()))</pre>
743 +         * This ensures that the {@code equals} method works properly across
744 +         * different implementations of the {@code Map.Entry} interface.
745 +         *
746 +         * @param o object to be compared for equality with this map entry
747 +         * @return {@code true} if the specified object is equal to this map
748 +         *         entry
749 +         * @see    #hashCode
750 +         */
751          public boolean equals(Object o) {
752              if (!(o instanceof Map.Entry))
753                  return false;
# Line 691 | Line 755 | public abstract class AbstractMap<K,V> i
755              return eq(key, e.getKey()) && eq(value, e.getValue());
756          }
757  
758 +        /**
759 +         * Returns the hash code value for this map entry.  The hash code
760 +         * of a map entry {@code e} is defined to be: <pre>
761 +         *   (e.getKey()==null   ? 0 : e.getKey().hashCode()) ^
762 +         *   (e.getValue()==null ? 0 : e.getValue().hashCode())</pre>
763 +         * This ensures that {@code e1.equals(e2)} implies that
764 +         * {@code e1.hashCode()==e2.hashCode()} for any two Entries
765 +         * {@code e1} and {@code e2}, as required by the general
766 +         * contract of {@link Object#hashCode}.
767 +         *
768 +         * @return the hash code value for this map entry
769 +         * @see    #equals
770 +         */
771          public int hashCode() {
772 <            return ((key   == null)   ? 0 :   key.hashCode()) ^
773 <                   ((value == null)   ? 0 : value.hashCode());
772 >            return (key   == null ? 0 :   key.hashCode()) ^
773 >                   (value == null ? 0 : value.hashCode());
774          }
775  
776          /**

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines