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. |
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); |
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. |
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) { |
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) { |
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> { |
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 |
|
} |
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 |
|
} |
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 |
|
|