Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to put an Entry into a Map?

Is there any way that I can put a whole Entry object to a Map object like:

map.put(entry);

instead of passing a key-value pair like:

map.put(key,value);
like image 354
pgmank Avatar asked Sep 11 '16 22:09

pgmank


3 Answers

I have searched on the Map interface methods but there is no method that takes an entry and puts it in the map. Therefore I have implemented it by myself using a little bit of inheritance and Java 8 interfaces.

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class Maps {

    // Test method
    public static void main(String[] args) {
        Map.Entry<String, String> entry1 = newEntry("Key1", "Value1");
        Map.Entry<String, String> entry2 = newEntry("Key2", "Value2");

        System.out.println("HashMap");
        MyMap<String, String> hashMap = new MyHashMap<>();
        hashMap.put(entry1);
        hashMap.put(entry2);

        for (String key : hashMap.keySet()) {
            System.out.println(key + " = " + hashMap.get(key));
        }

        System.out.println("\nTreeMap");
        MyMap<String, String> treeMap = new MyTreeMap<>();
        treeMap.put(entry1);
        treeMap.put(entry2);


        for (String key : treeMap.keySet()) {
            System.out.println(key + " = " + treeMap.get(key));
        }
    }


    /**
     * Creates a new Entry object given a key-value pair.
     * This is just a helper method for concisely creating a new Entry.
     * @param key   key of the entry
     * @param value value of the entry
     * 
     * @return  the Entry object containing the given key-value pair
     */
    private static <K,V> Map.Entry<K,V> newEntry(K key, V value) {
        return new AbstractMap.SimpleEntry<>(key, value);
    }

    /**
     * An enhanced Map interface.
     */
    public static interface MyMap<K,V> extends Map<K,V> {

        /**
         * Puts a whole entry containing a key-value pair to the map.
         * @param entry 
         */
        public default V put(Entry<K,V> entry) {
            return put(entry.getKey(), entry.getValue());
        }
    }

    /**
     * An enhanced HashMap class.
     */
    public static class MyHashMap<K,V> extends HashMap<K,V> implements MyMap<K,V> {}

    /**
     * An enhanced TreeMap class.
     */
    public static class MyTreeMap<K,V> extends TreeMap<K,V> implements MyMap<K,V> {}
}

The MyMap interface is just an interface that extends the Map interface by adding one more method, the public default V put(Entry<K,V> entry). Apart from just defining the method, a default implementation is coded too. Doing that, we can now add this method to any class that implements the Map interface just by defining a new class that implements the MyMap interface and extending the map implementation class of our choice. All of that in one line! This is demonstrated in the bottom of the code above where two classes are created each extending the HashMap and the TreeMap implementations.

like image 180
pgmank Avatar answered Nov 20 '22 00:11

pgmank


To instantiate a Map with Entries (in the same way as you can do Arrays.asList(T... a) or Sets.newHashSet(T... a) in Google Guava library, I found this:

import java.util.AbstractMap;
import java.util.Map;

public class MapWithEntries {

    private static final Map.Entry<String, String> ENTRY_1 = new AbstractMap.SimpleEntry<>("A", "Hello");
    private static final Map.Entry<String, String> ENTRY_2 = new AbstractMap.SimpleEntry<>("B", "World");

    private static final Map<String, String> MAP_WITH_ENTRIES = Map.ofEntries(ENTRY_1, ENTRY_2);
}
like image 26
Matt De Poorter Avatar answered Nov 20 '22 01:11

Matt De Poorter


Guava's ImmutableMap.Builder takes entries directly.

Obviously that doesn't directly modify an existing Map, but it might well scratch the same itch.

like image 1
mattlaw Avatar answered Nov 19 '22 23:11

mattlaw