Imagine the following scenario. You have a set of values which are already accessible and known. You have to put them into a HashMap for reasons.
Code example:
String a = "a";
Strinb b = "b";
...
HashMap map = new HashMap(5);
map.put("a", a);
map.put("b", b);
...
Is it really necessary to do it like this? I can't believe that there is not a constructor which let you put in your values from scratch.
I'm talking about something like this:
HashMap map = new HashMap(<"a", a>, <"b", b>, ...);
Or even something like this:
HashMap map = new HashMap(5);
HashMap.putBunchOfStuff("a", a, "b", b, ...);
Edit: My intention was to ask if there is a method but more importantly, if the answer is "no", why there isn't such a constructor/method.
HashMap stores key, value pairs and it does not allow duplicate keys. If the key is duplicate then the old key is replaced with the new value.
HashMap is similar to HashTable, but it is unsynchronized. It allows to store the null keys as well, but there should be only one null key object and there can be any number of null values. This class makes no guarantees as to the order of the map. To use this class and its methods, you need to import java.
What will happen if we attempt to add duplicate values ? Ans. No, We cannot have duplicate keys in HashMap. If we attempt to do so , the previous value for the key is overwritten.
Unfortunately, collection literals were a proposal for Project Coin in Java 7 (and Java 8), but it never made it into the final product, aka it is not a feature of Java.
The proposition was this
Here’s how it would look with map literals:
final Map<Integer, String> platonicSolids = {
4 : "tetrahedron",
6 : "cube",
8 : "octahedron",
12 : "dodecahedron",
20 : "icosahedron"
};
Here is the empty map literal, which has a slightly irregular syntax to make
it differ from the empty set:
Map<String, Integer> noJokeHere = { : };
BUT it never happened, so unfortunately that doesn't work. So unless you write your own magic builder or fancy lambda like on this site of Per-Åke Minborg, you're on your own. The following from the site should work, though (in Java 8).
//copy paste from linked site
Map<Integer, String> map = Stream.of(
new SimpleEntry<>(0, "zero"),
new SimpleEntry<>(1, "one"),
//...
new SimpleEntry<>(11, "eleven"),
new SimpleEntry<>(12, "twelve"))
.collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue()));
And the simplified version, also from the site:
//copy paste from linked site
public static <K, V> Map.Entry<K, V> entry(K key, V value) {
return new AbstractMap.SimpleEntry<>(key, value);
}
public static <K, U> Collector<Map.Entry<K, U>, ?, Map<K, U>> entriesToMap() {
return Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue());
}
Map<Integer, String> map = Stream.of(
entry(0, "zero"),
//...
entry(12, "twelve"))
.collect(entriesToMap());
Collection literals weren't introduced because of these points:
The "simple" version of this feature (sets, lists, maps only) is not very satisfying or popular; the "extensible" version of this feature is open-ended, messy, and virtually guaranteed to way overrun its design budget;
The library-based version gives us X% of the benefit for 1% of the cost, where X >> 1;
Value types are coming, and the "what would this feature look like" in a world with value types may well be quite different than in a world without, suggesting it would be questionable to try and do this work before value types;
We are better off focusing our language-design bandwidth on addressing more the foundational issues underlying a library-based version (including: more efficient varargs, array constants in the constant pool, immutable arrays, and support for caching (and reclaiming under pressure) intermediate immutable results).
By Brian Goetz from Oracle
There's no such constructor by default - you could use the double-brace idiom to put
all values in the map on instantiation, but this still requires multiple put calls:
Map<String,String> map = new HashMap<>() {{
put("a", "val1");
put("b", "val2");
//etc.
}};
In reality you usually have large blocks of data you want to put into a map accessible from a stream or another collection, so it's trivial to loop over multiple put
calls in this instance.
Guava has a putAll()
on its ImmutableMap.Builder
, enabling you to do something similar to this before instantiation. Other external libraries may have other similar behaviour, but fact is you'll have to resort to using external libraries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With