998 } |
998 } |
999 } |
999 } |
1000 return null; |
1000 return null; |
1001 } |
1001 } |
1002 |
1002 |
|
1003 /** |
|
1004 * {@inheritDoc} |
|
1005 * |
|
1006 * <p>This method will, on a best-effort basis, throw a |
|
1007 * {@link java.util.ConcurrentModificationException} if the mapping |
|
1008 * function modified this map during computation. |
|
1009 * |
|
1010 * @throws ConcurrentModificationException if it is detected that the |
|
1011 * mapping function modified this map |
|
1012 */ |
1003 @Override |
1013 @Override |
1004 public synchronized V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { |
1014 public synchronized V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { |
1005 Objects.requireNonNull(mappingFunction); |
1015 Objects.requireNonNull(mappingFunction); |
1006 |
1016 |
1007 Entry<?,?> tab[] = table; |
1017 Entry<?,?> tab[] = table; |
1014 // Hashtable not accept null value |
1024 // Hashtable not accept null value |
1015 return e.value; |
1025 return e.value; |
1016 } |
1026 } |
1017 } |
1027 } |
1018 |
1028 |
|
1029 int mc = modCount; |
1019 V newValue = mappingFunction.apply(key); |
1030 V newValue = mappingFunction.apply(key); |
|
1031 if (mc != modCount) { throw new ConcurrentModificationException(); } |
1020 if (newValue != null) { |
1032 if (newValue != null) { |
1021 addEntry(hash, key, newValue, index); |
1033 addEntry(hash, key, newValue, index); |
1022 } |
1034 } |
1023 |
1035 |
1024 return newValue; |
1036 return newValue; |
1025 } |
1037 } |
1026 |
1038 |
|
1039 /** |
|
1040 * {@inheritDoc} |
|
1041 * |
|
1042 * <p>This method will, on a best-effort basis, throw a |
|
1043 * {@link java.util.ConcurrentModificationException} if the remapping |
|
1044 * function modified this map during computation. |
|
1045 * |
|
1046 * @throws ConcurrentModificationException if it is detected that the |
|
1047 * remapping function modified this map |
|
1048 */ |
1027 @Override |
1049 @Override |
1028 public synchronized V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { |
1050 public synchronized V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { |
1029 Objects.requireNonNull(remappingFunction); |
1051 Objects.requireNonNull(remappingFunction); |
1030 |
1052 |
1031 Entry<?,?> tab[] = table; |
1053 Entry<?,?> tab[] = table; |
1033 int index = (hash & 0x7FFFFFFF) % tab.length; |
1055 int index = (hash & 0x7FFFFFFF) % tab.length; |
1034 @SuppressWarnings("unchecked") |
1056 @SuppressWarnings("unchecked") |
1035 Entry<K,V> e = (Entry<K,V>)tab[index]; |
1057 Entry<K,V> e = (Entry<K,V>)tab[index]; |
1036 for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) { |
1058 for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) { |
1037 if (e.hash == hash && e.key.equals(key)) { |
1059 if (e.hash == hash && e.key.equals(key)) { |
|
1060 int mc = modCount; |
1038 V newValue = remappingFunction.apply(key, e.value); |
1061 V newValue = remappingFunction.apply(key, e.value); |
|
1062 if (mc != modCount) { |
|
1063 throw new ConcurrentModificationException(); |
|
1064 } |
1039 if (newValue == null) { |
1065 if (newValue == null) { |
1040 if (prev != null) { |
1066 if (prev != null) { |
1041 prev.next = e.next; |
1067 prev.next = e.next; |
1042 } else { |
1068 } else { |
1043 tab[index] = e.next; |
1069 tab[index] = e.next; |
1044 } |
1070 } |
1045 modCount++; |
1071 modCount = mc + 1; |
1046 count--; |
1072 count--; |
1047 } else { |
1073 } else { |
1048 e.value = newValue; |
1074 e.value = newValue; |
1049 } |
1075 } |
1050 return newValue; |
1076 return newValue; |
1051 } |
1077 } |
1052 } |
1078 } |
1053 return null; |
1079 return null; |
1054 } |
1080 } |
1055 |
1081 /** |
|
1082 * {@inheritDoc} |
|
1083 * |
|
1084 * <p>This method will, on a best-effort basis, throw a |
|
1085 * {@link java.util.ConcurrentModificationException} if the remapping |
|
1086 * function modified this map during computation. |
|
1087 * |
|
1088 * @throws ConcurrentModificationException if it is detected that the |
|
1089 * remapping function modified this map |
|
1090 */ |
1056 @Override |
1091 @Override |
1057 public synchronized V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { |
1092 public synchronized V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { |
1058 Objects.requireNonNull(remappingFunction); |
1093 Objects.requireNonNull(remappingFunction); |
1059 |
1094 |
1060 Entry<?,?> tab[] = table; |
1095 Entry<?,?> tab[] = table; |
1062 int index = (hash & 0x7FFFFFFF) % tab.length; |
1097 int index = (hash & 0x7FFFFFFF) % tab.length; |
1063 @SuppressWarnings("unchecked") |
1098 @SuppressWarnings("unchecked") |
1064 Entry<K,V> e = (Entry<K,V>)tab[index]; |
1099 Entry<K,V> e = (Entry<K,V>)tab[index]; |
1065 for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) { |
1100 for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) { |
1066 if (e.hash == hash && Objects.equals(e.key, key)) { |
1101 if (e.hash == hash && Objects.equals(e.key, key)) { |
|
1102 int mc = modCount; |
1067 V newValue = remappingFunction.apply(key, e.value); |
1103 V newValue = remappingFunction.apply(key, e.value); |
|
1104 if (mc != modCount) { |
|
1105 throw new ConcurrentModificationException(); |
|
1106 } |
1068 if (newValue == null) { |
1107 if (newValue == null) { |
1069 if (prev != null) { |
1108 if (prev != null) { |
1070 prev.next = e.next; |
1109 prev.next = e.next; |
1071 } else { |
1110 } else { |
1072 tab[index] = e.next; |
1111 tab[index] = e.next; |
1073 } |
1112 } |
1074 modCount++; |
1113 modCount = mc + 1; |
1075 count--; |
1114 count--; |
1076 } else { |
1115 } else { |
1077 e.value = newValue; |
1116 e.value = newValue; |
1078 } |
1117 } |
1079 return newValue; |
1118 return newValue; |
1080 } |
1119 } |
1081 } |
1120 } |
1082 |
1121 |
|
1122 int mc = modCount; |
1083 V newValue = remappingFunction.apply(key, null); |
1123 V newValue = remappingFunction.apply(key, null); |
|
1124 if (mc != modCount) { throw new ConcurrentModificationException(); } |
1084 if (newValue != null) { |
1125 if (newValue != null) { |
1085 addEntry(hash, key, newValue, index); |
1126 addEntry(hash, key, newValue, index); |
1086 } |
1127 } |
1087 |
1128 |
1088 return newValue; |
1129 return newValue; |
1089 } |
1130 } |
1090 |
1131 |
|
1132 /** |
|
1133 * {@inheritDoc} |
|
1134 * |
|
1135 * <p>This method will, on a best-effort basis, throw a |
|
1136 * {@link java.util.ConcurrentModificationException} if the remapping |
|
1137 * function modified this map during computation. |
|
1138 * |
|
1139 * @throws ConcurrentModificationException if it is detected that the |
|
1140 * remapping function modified this map |
|
1141 */ |
1091 @Override |
1142 @Override |
1092 public synchronized V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { |
1143 public synchronized V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { |
1093 Objects.requireNonNull(remappingFunction); |
1144 Objects.requireNonNull(remappingFunction); |
1094 |
1145 |
1095 Entry<?,?> tab[] = table; |
1146 Entry<?,?> tab[] = table; |
1097 int index = (hash & 0x7FFFFFFF) % tab.length; |
1148 int index = (hash & 0x7FFFFFFF) % tab.length; |
1098 @SuppressWarnings("unchecked") |
1149 @SuppressWarnings("unchecked") |
1099 Entry<K,V> e = (Entry<K,V>)tab[index]; |
1150 Entry<K,V> e = (Entry<K,V>)tab[index]; |
1100 for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) { |
1151 for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) { |
1101 if (e.hash == hash && e.key.equals(key)) { |
1152 if (e.hash == hash && e.key.equals(key)) { |
|
1153 int mc = modCount; |
1102 V newValue = remappingFunction.apply(e.value, value); |
1154 V newValue = remappingFunction.apply(e.value, value); |
|
1155 if (mc != modCount) { |
|
1156 throw new ConcurrentModificationException(); |
|
1157 } |
1103 if (newValue == null) { |
1158 if (newValue == null) { |
1104 if (prev != null) { |
1159 if (prev != null) { |
1105 prev.next = e.next; |
1160 prev.next = e.next; |
1106 } else { |
1161 } else { |
1107 tab[index] = e.next; |
1162 tab[index] = e.next; |
1108 } |
1163 } |
1109 modCount++; |
1164 modCount = mc + 1; |
1110 count--; |
1165 count--; |
1111 } else { |
1166 } else { |
1112 e.value = newValue; |
1167 e.value = newValue; |
1113 } |
1168 } |
1114 return newValue; |
1169 return newValue; |