Это легко доказать:
private static <K, V> void debugResize(Map<K, V> map, K key, V value) throws Throwable {
Field table = map.getClass().getDeclaredField("table");
AccessibleObject.setAccessible(new Field[] { table }, true);
Object[] nodes = ((Object[]) table.get(map));
// first put
if (nodes == null) {
map.put(key, value);
return;
}
map.put(key, value);
Field field = map.getClass().getDeclaredField("table");
AccessibleObject.setAccessible(new Field[] { field }, true);
int x = ((Object[]) field.get(map)).length;
if (nodes.length != x) {
++currentResizeCalls;
}
}
И какое-то использование:
static int currentResizeCalls = 0;
public static void main(String[] args) throws Throwable {
int size = 100;
Map<Integer, String> m = new HashMap<>(size);
for (int i = 0; i < size; i++) {
DeleteMe.debugResize(m, i, String.valueOf(i));
}
System.out.println(DeleteMe.currentResizeCalls);
}
Я регистрирую только время, которое требуется, когда resize
на самом деле изменяет размер, потому что первый вызов инициализируется;как указано в документации:
Инициализирует или удваивает размер таблицы
Второй из ваших пунктов гораздо интереснее. A HashMap
определяет capacity
, теперь какая емкость?И это не так очевидно:
Для HashMap
, capacity
- это число buckets
до изменения размера, для ConcurrentHashMap
это количество записей до изменения размера.
Таким образом, чтобы не вызывать resize внутри, в случае HashMap
используйте формулу:
(int)(1.0 + (long)initialCapacity / LOAD_FACTOR)
Но это далеко не идеал, скажем, вы хотите 1024
записей без изменения размера,используя эту формулу, вы получаете 1367
сегментов, которые внутренне округляются до степени двойки, таким образом, 2048
- ну, намного больше, чем вы просили.
Для CHM
укажите размер напрямую .Легко доказать, используя одну единственную модификацию в предыдущем коде:
// use CHM instead of HashMap
Map<Integer, String> m = new ConcurrentHashMap<>(size);
Это приведет к zero
изменениям размера, которые фактически удваивают массив.Но иногда даже CHM
внутренний код сбивает с толку и требует небольшого количества исправлений.