I'm trying to write a simple utility function to get a value from a Map and, if it's not found to create a new value class and put that in the map.
It seems though very difficult to get the classes of the map's key and value at runtime and the best I can come up with is something horrible along the following lines.
Is there a better way?
private Object getOrCreate( Map<Object, Object> map, Object key, Class<?> mapValueClass ) {
Object value = map.get( key );
if (value == null) {
Constructor<?> con = mapValueClass.getConstructor( key.getClass() );
value = con.newInstance( key );
map.put( key, value );
}
return value;
}
Since version 9, Java has a static method entry() in the Map interface to create an Entry: Map. Entry<String, String> entry = Map.
put() method of HashMap is used to insert a mapping into a map. This means we can insert a specific key and the value it is mapping to into a particular map. If an existing key is passed then the previous value gets replaced by the new value. If a new pair is passed, then the pair gets inserted as a whole.
A map entry (key-value pair). The Map. entrySet method returns a collection-view of the map, whose elements are of this class. The only way to obtain a reference to a map entry is from the iterator of this collection-view.
Map. Entry interface in Java provides certain methods to access the entry in the Map. By gaining access to the entry of the Map we can easily manipulate them.
You should ckeck out Map::getOrDefault
and Map::computeIfAbsent
(added in Java 8); those do pretty much exactly what your function is supposed to do. The difference between the two is that getOrDefault
will accept an existing instance (created before the method is invoked) and return it if needed, but will not add it to the map, while computeIfAbsend
accepts a function for lazily creating a new value, and will also add that value to the map.
Map<String, List<Integer>> map = new HashMap<>();
List<Integer> list1 = map.getOrDefault("foo", Collections.emptyList());
System.out.println(list1); // empty list
System.out.println(map); // map is still empty
List<Integer> list2 = map.computeIfAbsent("bar", s -> new ArrayList<Integer>());
System.out.println(list2); // empty list
System.out.println(map); // entry added to map
Assuming that you always want to create a new instance of the Value class with the key as parameter, and assuming that that class actually has such a constructor) you could e.g. use this:
YourClass obj = map.computeIfAbsent(key, YourClass::new);
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