Skip to content

Commit 87faa85

Browse files
XenoAmessStuart Marks
authored andcommitted
8186958: Need method to create pre-sized HashMap
Reviewed-by: chegar, naoto, joehw, lancea, wetmore, smarks
1 parent 41fc078 commit 87faa85

File tree

30 files changed

+208
-73
lines changed

30 files changed

+208
-73
lines changed

src/java.base/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -570,7 +570,7 @@ public Map<String, Integer> getDisplayNames(String calendarType,
570570
String[] names = getCalendarDisplayStrings(locale.toLanguageTag(),
571571
field, style);
572572
if (names != null) {
573-
map = new HashMap<>((int)Math.ceil(names.length / 0.75));
573+
map = HashMap.newHashMap(names.length);
574574
for (int value = 0; value < names.length; value++) {
575575
if (names[value] != null) {
576576
map.put(names[value], value);

src/java.base/share/classes/java/lang/Character.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -744,8 +744,7 @@ public static final class UnicodeBlock extends Subset {
744744
* 0.75 - the default load factor of HashMap
745745
*/
746746
private static final int NUM_ENTITIES = 737;
747-
private static Map<String, UnicodeBlock> map =
748-
new HashMap<>((int)(NUM_ENTITIES / 0.75f + 1.0f));
747+
private static Map<String, UnicodeBlock> map = HashMap.newHashMap(NUM_ENTITIES);
749748

750749
/**
751750
* Creates a UnicodeBlock with the given identifier name.
@@ -8572,7 +8571,7 @@ public static enum UnicodeScript {
85728571

85738572
private static final HashMap<String, Character.UnicodeScript> aliases;
85748573
static {
8575-
aliases = new HashMap<>((int)(162 / 0.75f + 1.0f));
8574+
aliases = HashMap.newHashMap(162);
85768575
aliases.put("ADLM", ADLAM);
85778576
aliases.put("AGHB", CAUCASIAN_ALBANIAN);
85788577
aliases.put("AHOM", AHOM);

src/java.base/share/classes/java/lang/Class.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3910,7 +3910,7 @@ Map<String, T> enumConstantDirectory() {
39103910
if (universe == null)
39113911
throw new IllegalArgumentException(
39123912
getName() + " is not an enum class");
3913-
directory = new HashMap<>((int)(universe.length / 0.75f) + 1);
3913+
directory = HashMap.newHashMap(universe.length);
39143914
for (T constant : universe) {
39153915
directory.put(((Enum<?>)constant).name(), constant);
39163916
}
@@ -4125,10 +4125,10 @@ private AnnotationData createAnnotationData(int classRedefinedCount) {
41254125
Class<? extends Annotation> annotationClass = e.getKey();
41264126
if (AnnotationType.getInstance(annotationClass).isInherited()) {
41274127
if (annotations == null) { // lazy construction
4128-
annotations = new LinkedHashMap<>((Math.max(
4128+
annotations = LinkedHashMap.newLinkedHashMap(Math.max(
41294129
declaredAnnotations.size(),
41304130
Math.min(12, declaredAnnotations.size() + superAnnotations.size())
4131-
) * 4 + 2) / 3
4131+
)
41324132
);
41334133
}
41344134
annotations.put(annotationClass, e.getValue());

src/java.base/share/classes/java/lang/Module.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -980,7 +980,7 @@ void implAddOpensToAllUnnamed(Set<String> concealedPkgs, Set<String> exportedPkg
980980
// the packages to all unnamed modules.
981981
Map<String, Set<Module>> openPackages = this.openPackages;
982982
if (openPackages == null) {
983-
openPackages = new HashMap<>((4 * (concealedPkgs.size() + exportedPkgs.size()) / 3) + 1);
983+
openPackages = HashMap.newHashMap(concealedPkgs.size() + exportedPkgs.size());
984984
} else {
985985
openPackages = new HashMap<>(openPackages);
986986
}
@@ -1133,8 +1133,7 @@ static Map<String, Module> defineModules(Configuration cf,
11331133
boolean isBootLayer = (ModuleLayer.boot() == null);
11341134

11351135
int numModules = cf.modules().size();
1136-
int cap = (int)(numModules / 0.75f + 1.0f);
1137-
Map<String, Module> nameToModule = new HashMap<>(cap);
1136+
Map<String, Module> nameToModule = HashMap.newHashMap(numModules);
11381137

11391138
// to avoid repeated lookups and reduce iteration overhead, we create
11401139
// arrays holding correlated information about each module.

src/java.base/share/classes/java/lang/Thread.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1655,7 +1655,7 @@ public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
16551655
// Get a snapshot of the list of all threads
16561656
Thread[] threads = getThreads();
16571657
StackTraceElement[][] traces = dumpThreads(threads);
1658-
Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
1658+
Map<Thread, StackTraceElement[]> m = HashMap.newHashMap(threads.length);
16591659
for (int i = 0; i < threads.length; i++) {
16601660
StackTraceElement[] stackTrace = traces[i];
16611661
if (stackTrace != null) {

src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -290,7 +290,7 @@ static MethodHandle makePairwiseConvertByEditor(MethodHandle target, MethodType
290290
BoundMethodHandle mh = target.rebind();
291291

292292
// Match each unique conversion to the positions at which it is to be applied
293-
var convSpecMap = new HashMap<Object, int[]>(((4 * convCount) / 3) + 1);
293+
HashMap<Object, int[]> convSpecMap = HashMap.newHashMap(convCount);
294294
for (int i = 0; i < convSpecs.length - MH_RECEIVER_OFFSET; i++) {
295295
Object convSpec = convSpecs[i];
296296
if (convSpec == null) continue;

src/java.base/share/classes/java/lang/module/Resolver.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -498,12 +498,11 @@ private void checkHashes() {
498498
*/
499499
private Map<ResolvedModule, Set<ResolvedModule>> makeGraph(Configuration cf) {
500500

501-
// initial capacity of maps to avoid resizing
502-
int capacity = 1 + (4 * nameToReference.size())/ 3;
501+
int moduleCount = nameToReference.size();
503502

504503
// the "reads" graph starts as a module dependence graph and
505504
// is iteratively updated to be the readability graph
506-
Map<ResolvedModule, Set<ResolvedModule>> g1 = new HashMap<>(capacity);
505+
Map<ResolvedModule, Set<ResolvedModule>> g1 = HashMap.newHashMap(moduleCount);
507506

508507
// the "requires transitive" graph, contains requires transitive edges only
509508
Map<ResolvedModule, Set<ResolvedModule>> g2;
@@ -512,7 +511,7 @@ private Map<ResolvedModule, Set<ResolvedModule>> makeGraph(Configuration cf) {
512511
// as there may be selected modules that have a dependency on modules in
513512
// the parent configuration.
514513
if (ModuleLayer.boot() == null) {
515-
g2 = new HashMap<>(capacity);
514+
g2 = HashMap.newHashMap(moduleCount);
516515
} else {
517516
g2 = parents.stream()
518517
.flatMap(Configuration::configurations)
@@ -539,7 +538,7 @@ private Map<ResolvedModule, Set<ResolvedModule>> makeGraph(Configuration cf) {
539538

540539
// populate g1 and g2 with the dependences from the selected modules
541540

542-
Map<String, ResolvedModule> nameToResolved = new HashMap<>(capacity);
541+
Map<String, ResolvedModule> nameToResolved = HashMap.newHashMap(moduleCount);
543542

544543
for (ModuleReference mref : nameToReference.values()) {
545544
ModuleDescriptor descriptor = mref.descriptor();

src/java.base/share/classes/java/security/cert/CertificateRevokedException.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -245,7 +245,7 @@ private void readObject(ObjectInputStream ois)
245245
} else if (size < 0) {
246246
throw new IOException("size cannot be negative");
247247
} else {
248-
extensions = new HashMap<>(size > 20 ? 20 : size);
248+
extensions = HashMap.newHashMap(size > 20 ? 20 : size);
249249
}
250250

251251
// Read in the extensions and put the mappings in the extensions map

src/java.base/share/classes/java/security/cert/PKIXRevocationChecker.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -197,7 +197,7 @@ public void setOcspResponses(Map<X509Certificate, byte[]> responses)
197197
if (responses == null) {
198198
this.ocspResponses = Collections.<X509Certificate, byte[]>emptyMap();
199199
} else {
200-
Map<X509Certificate, byte[]> copy = new HashMap<>(responses.size());
200+
Map<X509Certificate, byte[]> copy = HashMap.newHashMap(responses.size());
201201
for (Map.Entry<X509Certificate, byte[]> e : responses.entrySet()) {
202202
copy.put(e.getKey(), e.getValue().clone());
203203
}
@@ -216,7 +216,7 @@ public void setOcspResponses(Map<X509Certificate, byte[]> responses)
216216
* Returns an empty map if no responses have been specified.
217217
*/
218218
public Map<X509Certificate, byte[]> getOcspResponses() {
219-
Map<X509Certificate, byte[]> copy = new HashMap<>(ocspResponses.size());
219+
Map<X509Certificate, byte[]> copy = HashMap.newHashMap(ocspResponses.size());
220220
for (Map.Entry<X509Certificate, byte[]> e : ocspResponses.entrySet()) {
221221
copy.put(e.getKey(), e.getValue().clone());
222222
}

src/java.base/share/classes/java/util/HashMap.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -433,6 +433,10 @@ static final int tableSizeFor(int cap) {
433433
* Constructs an empty {@code HashMap} with the specified initial
434434
* capacity and load factor.
435435
*
436+
* @apiNote
437+
* To create a {@code HashMap} with an initial capacity that accommodates
438+
* an expected number of mappings, use {@link #newHashMap(int) newHashMap}.
439+
*
436440
* @param initialCapacity the initial capacity
437441
* @param loadFactor the load factor
438442
* @throws IllegalArgumentException if the initial capacity is negative
@@ -455,6 +459,10 @@ public HashMap(int initialCapacity, float loadFactor) {
455459
* Constructs an empty {@code HashMap} with the specified initial
456460
* capacity and the default load factor (0.75).
457461
*
462+
* @apiNote
463+
* To create a {@code HashMap} with an initial capacity that accommodates
464+
* an expected number of mappings, use {@link #newHashMap(int) newHashMap}.
465+
*
458466
* @param initialCapacity the initial capacity.
459467
* @throws IllegalArgumentException if the initial capacity is negative.
460468
*/
@@ -2545,4 +2553,32 @@ static <K,V> boolean checkInvariants(TreeNode<K,V> t) {
25452553
}
25462554
}
25472555

2556+
/**
2557+
* Calculate initial capacity for HashMap based classes, from expected size and default load factor (0.75).
2558+
*
2559+
* @param numMappings the expected number of mappings
2560+
* @return initial capacity for HashMap based classes.
2561+
* @since 19
2562+
*/
2563+
static int calculateHashMapCapacity(int numMappings) {
2564+
return (int) Math.ceil(numMappings / (double) DEFAULT_LOAD_FACTOR);
2565+
}
2566+
2567+
/**
2568+
* Creates a new, empty HashMap suitable for the expected number of mappings.
2569+
* The returned map uses the default load factor of 0.75, and its initial capacity is
2570+
* generally large enough so that the expected number of mappings can be added
2571+
* without resizing the map.
2572+
*
2573+
* @param numMappings the expected number of mappings
2574+
* @param <K> the type of keys maintained by this map
2575+
* @param <V> the type of mapped values
2576+
* @return the newly created map
2577+
* @throws IllegalArgumentException if numMappings is negative
2578+
* @since 19
2579+
*/
2580+
public static <K, V> HashMap<K, V> newHashMap(int numMappings) {
2581+
return new HashMap<>(calculateHashMapCapacity(numMappings));
2582+
}
2583+
25482584
}

0 commit comments

Comments
 (0)