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

Comparing jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java (file contents):
Revision 1.75 by jsr166, Thu Jun 16 02:17:07 2005 UTC vs.
Revision 1.83 by jsr166, Mon Aug 22 03:42:10 2005 UTC

# Line 611 | Line 611 | public class ConcurrentHashMap<K, V> ext
611  
612      /**
613       * Creates a new, empty map with the specified initial capacity
614 <     * and load factor and with the default concurrencyLevel
615 <     * (<tt>16</tt>).
614 >     * and load factor and with the default concurrencyLevel (16).
615       *
616       * @param initialCapacity The implementation performs internal
617       * sizing to accommodate this many elements.
# Line 621 | Line 620 | public class ConcurrentHashMap<K, V> ext
620       * bin exceeds this threshold.
621       * @throws IllegalArgumentException if the initial capacity of
622       * elements is negative or the load factor is nonpositive
623 +     *
624 +     * @since 1.6
625       */
626      public ConcurrentHashMap(int initialCapacity, float loadFactor) {
627          this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL);
# Line 628 | Line 629 | public class ConcurrentHashMap<K, V> ext
629  
630      /**
631       * Creates a new, empty map with the specified initial capacity,
632 <     * and with default load factor (<tt>0.75f</tt>)
632 <     * and concurrencyLevel (<tt>16</tt>).
632 >     * and with default load factor (0.75) and concurrencyLevel (16).
633       *
634       * @param initialCapacity the initial capacity. The implementation
635       * performs internal sizing to accommodate this many elements.
# Line 641 | Line 641 | public class ConcurrentHashMap<K, V> ext
641      }
642  
643      /**
644 <     * Creates a new, empty map with a default initial capacity
645 <     * (<tt>16</tt>), load factor
646 <     * (<tt>0.75f</tt>), and concurrencyLevel
647 <     * (<tt>16</tt>).
644 >     * Creates a new, empty map with a default initial capacity (16),
645 >     * load factor (0.75) and concurrencyLevel (16).
646       */
647      public ConcurrentHashMap() {
648          this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
649      }
650  
651      /**
652 <     * Creates a new map with the same mappings as the given map.  The
653 <     * map is created with a capacity of 1.5 times the number of
654 <     * mappings in the given map or <tt>16</tt>
655 <     * (whichever is greater), and a default load factor
656 <     * (<tt>0.75f</tt>) and concurrencyLevel
659 <     * (<tt>16</tt>).
652 >     * Creates a new map with the same mappings as the given map.
653 >     * The map is created with a capacity of 1.5 times the number
654 >     * of mappings in the given map or 16 (whichever is greater),
655 >     * and a default load factor (0.75) and concurrencyLevel (16).
656 >     *
657       * @param m the map
658       */
659      public ConcurrentHashMap(Map<? extends K, ? extends V> m) {
# Line 757 | Line 754 | public class ConcurrentHashMap<K, V> ext
754       * <tt>null</tt> if the map contains no mapping for the key.
755       *
756       * @param key key whose associated value is to be returned
757 <     * @return the value associated with <tt>key</tt> in this map, or
758 <     *         <tt>null</tt> if there is no mapping for <tt>key</tt>
757 >     * @return the value to which this map maps the specified key, or
758 >     *         <tt>null</tt> if the map contains no mapping for the key
759       * @throws NullPointerException if the specified key is null
760       */
761      public V get(Object key) {
# Line 1109 | Line 1106 | public class ConcurrentHashMap<K, V> ext
1106          }
1107      }
1108  
1109 <    final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
1110 <        public K next() { return super.nextEntry().key; }
1109 >    final class KeyIterator
1110 >        extends HashIterator
1111 >        implements Iterator<K>, Enumeration<K>
1112 >    {
1113 >        public K next()        { return super.nextEntry().key; }
1114          public K nextElement() { return super.nextEntry().key; }
1115      }
1116  
1117 <    final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
1118 <        public V next() { return super.nextEntry().value; }
1117 >    final class ValueIterator
1118 >        extends HashIterator
1119 >        implements Iterator<V>, Enumeration<V>
1120 >    {
1121 >        public V next()        { return super.nextEntry().value; }
1122          public V nextElement() { return super.nextEntry().value; }
1123      }
1124  
1122
1123
1125      /**
1126 <     * Entry iterator. Exported Entry objects must write-through
1127 <     * changes in setValue, even if the nodes have been cloned. So we
1127 <     * cannot return internal HashEntry objects. Instead, the iterator
1128 <     * itself acts as a forwarding pseudo-entry.
1126 >     * Custom Entry class used by EntryIterator.next(), that relays
1127 >     * setValue changes to the underlying map.
1128       */
1129 <    final class EntryIterator extends HashIterator implements Map.Entry<K,V>, Iterator<Entry<K,V>> {
1130 <        public Map.Entry<K,V> next() {
1131 <            nextEntry();
1132 <            return this;
1133 <        }
1134 <
1135 <        public K getKey() {
1136 <            if (lastReturned == null)
1137 <                throw new IllegalStateException("Entry was removed");
1138 <            return lastReturned.key;
1139 <        }
1140 <
1141 <        public V getValue() {
1142 <            if (lastReturned == null)
1143 <                throw new IllegalStateException("Entry was removed");
1144 <            return ConcurrentHashMap.this.get(lastReturned.key);
1145 <        }
1146 <
1147 <        public V setValue(V value) {
1148 <            if (lastReturned == null)
1149 <                throw new IllegalStateException("Entry was removed");
1151 <            return ConcurrentHashMap.this.put(lastReturned.key, value);
1152 <        }
1153 <
1154 <        public boolean equals(Object o) {
1155 <            // If not acting as entry, just use default.
1156 <            if (lastReturned == null)
1157 <                return super.equals(o);
1158 <            if (!(o instanceof Map.Entry))
1159 <                return false;
1160 <            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
1161 <            return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
1162 <        }
1163 <
1164 <        public int hashCode() {
1165 <            // If not acting as entry, just use default.
1166 <            if (lastReturned == null)
1167 <                return super.hashCode();
1168 <
1169 <            Object k = getKey();
1170 <            Object v = getValue();
1171 <            return ((k == null) ? 0 : k.hashCode()) ^
1172 <                   ((v == null) ? 0 : v.hashCode());
1173 <        }
1174 <
1175 <        public String toString() {
1176 <            // If not acting as entry, just use default.
1177 <            if (lastReturned == null)
1178 <                return super.toString();
1179 <            else
1180 <                return getKey() + "=" + getValue();
1129 >    final class WriteThroughEntry
1130 >        extends AbstractMap.SimpleEntry<K,V>
1131 >    {
1132 >        WriteThroughEntry(K k, V v) {
1133 >            super(k,v);
1134 >        }
1135 >
1136 >        /**
1137 >         * Set our entry's value and write through to the map. The
1138 >         * value to return is somewhat arbitrary here. Since a
1139 >         * WriteThroughEntry does not necessarily track asynchronous
1140 >         * changes, the most recent "previous" value could be
1141 >         * different from what we return (or could even have been
1142 >         * removed in which case the put will re-establish). We do not
1143 >         * and cannot guarantee more.
1144 >         */
1145 >        public V setValue(V value) {
1146 >            if (value == null) throw new NullPointerException();
1147 >            V v = super.setValue(value);
1148 >            ConcurrentHashMap.this.put(getKey(), value);
1149 >            return v;
1150          }
1151 +    }
1152  
1153 <        boolean eq(Object o1, Object o2) {
1154 <            return (o1 == null ? o2 == null : o1.equals(o2));
1153 >    final class EntryIterator
1154 >        extends HashIterator
1155 >        implements Iterator<Entry<K,V>>
1156 >    {
1157 >        public Map.Entry<K,V> next() {
1158 >            HashEntry<K,V> e = super.nextEntry();
1159 >            return new WriteThroughEntry(e.key, e.value);
1160          }
1186
1161      }
1162  
1163      final class KeySet extends AbstractSet<K> {
# Line 1203 | Line 1177 | public class ConcurrentHashMap<K, V> ext
1177              ConcurrentHashMap.this.clear();
1178          }
1179          public Object[] toArray() {
1180 <            Collection<K> c = new ArrayList<K>();
1181 <            for (Iterator<K> i = iterator(); i.hasNext(); )
1182 <                c.add(i.next());
1180 >            Collection<K> c = new ArrayList<K>(size());
1181 >            for (K k : this)
1182 >                c.add(k);
1183              return c.toArray();
1184          }
1185          public <T> T[] toArray(T[] a) {
1186              Collection<K> c = new ArrayList<K>();
1187 <            for (Iterator<K> i = iterator(); i.hasNext(); )
1188 <                c.add(i.next());
1187 >            for (K k : this)
1188 >                c.add(k);
1189              return c.toArray(a);
1190          }
1191      }
# Line 1230 | Line 1204 | public class ConcurrentHashMap<K, V> ext
1204              ConcurrentHashMap.this.clear();
1205          }
1206          public Object[] toArray() {
1207 <            Collection<V> c = new ArrayList<V>();
1208 <            for (Iterator<V> i = iterator(); i.hasNext(); )
1209 <                c.add(i.next());
1207 >            Collection<V> c = new ArrayList<V>(size());
1208 >            for (V v : this)
1209 >                c.add(v);
1210              return c.toArray();
1211          }
1212          public <T> T[] toArray(T[] a) {
1213 <            Collection<V> c = new ArrayList<V>();
1214 <            for (Iterator<V> i = iterator(); i.hasNext(); )
1215 <                c.add(i.next());
1213 >            Collection<V> c = new ArrayList<V>(size());
1214 >            for (V v : this)
1215 >                c.add(v);
1216              return c.toArray(a);
1217          }
1218      }
# Line 1267 | Line 1241 | public class ConcurrentHashMap<K, V> ext
1241              ConcurrentHashMap.this.clear();
1242          }
1243          public Object[] toArray() {
1270            // Since we don't ordinarily have distinct Entry objects, we
1271            // must pack elements using exportable SimpleEntry
1244              Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
1245 <            for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
1246 <                c.add(new AbstractMap.SimpleEntry<K,V>(i.next()));
1245 >            for (Map.Entry<K,V> e : this)
1246 >                c.add(e);
1247              return c.toArray();
1248          }
1249          public <T> T[] toArray(T[] a) {
1250              Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
1251 <            for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
1252 <                c.add(new AbstractMap.SimpleEntry<K,V>(i.next()));
1251 >            for (Map.Entry<K,V> e : this)
1252 >                c.add(e);
1253              return c.toArray(a);
1254          }
1255  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines