I'm looking for the best way (readability and efficiency) of providing a default value for a HashMap
get operation but to also have the underlying map updated with that default value if a value is not already present.
I understand there are 3rd party libraries out there, but I'd prefer to stick with standard Java. Here are some different ways I've thought of:
Old school
Map<String, List<Integer>> someIntegerListLookup = new HashMap<>();
String key = "key";
...
List<Integer> integerList = someIntegerListLookup.get(key);
if (integerList == null) {
integerList = new ArrayList<>();
someIntegerListLookup.put(key, integerList);
}
Java 8 Map methods
// getOrDefault
List<Integer> integerList = someIntegerListLookup.getOrDefault(key, new ArrayList<>());
someIntegerListLookup.put(key, integerList);
// putIfAbsent
someIntegerListLookup.putIfAbsent(key, new ArrayList<>());
List<Integer> integerList = someIntegerListLookup.get(key);
Using Java 8 Optionals
List<Integer> integerList =
Optional.ofNullable(someIntegerListLookup.putIfAbsent(key, new ArrayList<>()))
.orElse(someIntegerListLookup.get(key));
Not a fan of this approach from a readability point of view.
Using an 'or else' supplier:
List<Integer> integerList = Optional.ofNullable(someIntegerListLookup.get(key))
.orElseGet(() -> {
// Only runs if the map contains no value for the key
List<Integer> defaultIntegersList = new ArrayList<>();
someIntegerListLookup.put(key, defaultIntegersList);
return defaultIntegersList;
});
Right now I'm leaning towards the above solution being the best option. Are there other (better) solutions out there for this that I haven't thought of or come across?