Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get or create new map entry

Tags:

java

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;
}
like image 832
Ian Avatar asked Aug 20 '16 14:08

Ian


People also ask

How do you make a map entry?

Since version 9, Java has a static method entry() in the Map interface to create an Entry: Map. Entry<String, String> entry = Map.

How HashMap put a new entry and gets it?

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.

What is entry in map entry?

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.

Why do we use map entry?

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.


1 Answers

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);
like image 187
tobias_k Avatar answered Sep 28 '22 12:09

tobias_k