Is it possible to have a HashMap
return a default value for all keys that are not found in the set?
In mixed Java/Kotlin projects also consider Kotlin's Map.withDefault.
[Update]
As noted by other answers and commenters, as of Java 8 you can simply call Map#getOrDefault(...).
[Original]
There's no Map implementation that does this exactly but it would be trivial to implement your own by extending HashMap:
public class DefaultHashMap<K,V> extends HashMap<K,V> {
protected V defaultValue;
public DefaultHashMap(V defaultValue) {
this.defaultValue = defaultValue;
}
@Override
public V get(Object k) {
return containsKey(k) ? super.get(k) : defaultValue;
}
}
I found the LazyMap quite helpful.
When the get(Object) method is called with a key that does not exist in the map, the factory is used to create the object. The created object will be added to the map using the requested key.
This allows you to do something like this:
Map<String, AtomicInteger> map = LazyMap.lazyMap(new HashMap<>(), ()->new AtomicInteger(0));
map.get(notExistingKey).incrementAndGet();
The call to get
creates a default value for the given key. You specify how to create the default value with the factory argument to LazyMap.lazyMap(map, factory)
. In the example above, the map is initialized to a new AtomicInteger
with value 0.
Can't you just create a static method that does exactly this?
private static <K, V> V getOrDefault(Map<K,V> map, K key, V defaultValue) {
return map.containsKey(key) ? map.get(key) : defaultValue;
}
Use:
myHashMap.getOrDefault(key, defaultValue);
I needed to read the results returned from a server in JSON where I couldn't guarantee the fields would be present. I'm using class org.json.simple.JSONObject which is derived from HashMap. Here are some helper functions I employed:
public static String getString( final JSONObject response,
final String key )
{ return getString( response, key, "" ); }
public static String getString( final JSONObject response,
final String key, final String defVal )
{ return response.containsKey( key ) ? (String)response.get( key ) : defVal; }
public static long getLong( final JSONObject response,
final String key )
{ return getLong( response, key, 0 ); }
public static long getLong( final JSONObject response,
final String key, final long defVal )
{ return response.containsKey( key ) ? (long)response.get( key ) : defVal; }
public static float getFloat( final JSONObject response,
final String key )
{ return getFloat( response, key, 0.0f ); }
public static float getFloat( final JSONObject response,
final String key, final float defVal )
{ return response.containsKey( key ) ? (float)response.get( key ) : defVal; }
public static List<JSONObject> getList( final JSONObject response,
final String key )
{ return getList( response, key, new ArrayList<JSONObject>() ); }
public static List<JSONObject> getList( final JSONObject response,
final String key, final List<JSONObject> defVal ) {
try { return response.containsKey( key ) ? (List<JSONObject>) response.get( key ) : defVal; }
catch( ClassCastException e ) { return defVal; }
}