JavaRush /Java Blog /Random EN /Answers to the most popular questions about the Map inter...

Answers to the most popular questions about the Map interface

Published in the Random EN group
Hello! Today we will give answers to the most common questions about Map, but first, let's remember what it is. Answers to the most popular questions about the Map interface - 1A map is a data structure that contains a set of key-value pairs. Its data structure resembles a dictionary, which is why it is often called that. At the same time, Map is an interface , and in the standard jdk it contains the main implementations: Hashmap, LinkedHashMap, Hashtable, TreeMap. The most used implementation is Hashmap, so we will use it in our examples. This is what the standard creation and filling of a map looks like:
Map<Integer, String> map = new HashMap<>();
map.put(1, "string 1");
map.put(2, "string 2");
map.put(3, "string 3");
And this is how to get values ​​by key:
String string1 = map.get(1);
String string2 = map.get(2);
String string3 = map.get(3);
If all of the above is clear, let's proceed to our answers to popular questions!

0. How to iterate through all Map values

Iterating over values ​​is the most common operation you perform with maps. All key-value pairs are stored in the internal Map.Entry interface, and to get them you need to call the entrySet(). It returns a Set of pairs that can be looped through:
for(Map.Entry<Integer, String> entry: map.entrySet()) {
   // get key
   Integer key = entry.getKey();
   // get value
   String value = entry.getValue();
}

Или используя итератор:
Iterator<Map.Entry<Integer, String>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
   Map.Entry<Integer, String> entry =  itr.next();
   // get key
   Integer key = entry.getKey();
   // get value
   String value = entry.getValue();
}

1. How to convert Map to List

The Map interface has 3 methods that return a list of elements:
  • keySet() - returns a Set of keys;
  • values() - returns a Collection of values;
  • entrySet() - returns a Set of key-value sets.
If you look at the constructors of the class ArrayList, you will notice that there is a constructor with an argument of type Collection. Since Set is a descendant of Collection, the results of all the above methods can be passed to the constructor of the class ArrayList. So we will create new lists and fill them with values ​​from Map:
// key list
List<Integer> keyList = new ArrayList<>(map.keySet());
// value list
List<String> valueList = new ArrayList<>(map.values());
// key-value list
List<Map.Entry<Integer, String>> entryList = new ArrayList<>(map.entrySet());

2. How to sort map keys

Sorting maps is also a fairly common operation in programming. You can do this in several ways:
  1. Put Map.Entry into a list and sort it using Comparator .

    In the comparator we will compare only the keys of pairs:

    List> list = new ArrayList(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
       @Override
       public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
           return o1.getKey() - o2.getKey();
       }
    });
    

    If you understand lambdas, this entry can be significantly shortened:

    Collections.sort(list, Comparator.comparingInt(Map.Entry::getKey));
  2. Use SortedMap, or more precisely, its implementation TreeMap, which takes a Comparator in its constructor. This comparator will be applied to the map keys, so the keys must be classes that implement the interface Comparable:

    SortedMap<Integer, String> sortedMap = new TreeMap<>(new Comparator<Integer>() {
       @Override
       public int compare(Integer o1, Integer o2) {
           return o1 - o2;
       }
    });

    And, of course, everything can be rewritten using lambdas:

    SortedMap<Integer, String> sortedMap = new TreeMap<>(Comparator.comparingInt(o -> o));

    Unlike the first method, using SortedMap, we will always store the data in sorted form.

3. How to sort map values

Here you should use an approach similar to the first one for keys - get a list of values ​​and sort them in the list:
List <Map.Entry<Integer, String>> valuesList = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
   @Override
   public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
       return o1.getValue().compareTo(o2.getValue());
   }
});
And the lambda for this looks like this:
Collections.sort(list, Comparator.comparing(Map.Entry::getValue));

4. What is the difference between HashMap, TreeMap, and Hashtable

As mentioned earlier, there are 3 main implementations of the Map interface. Each of them has its own characteristics:
  1. Order of elements. HashMapand Hashtabledo not guarantee that items will be stored in the order they were added. In addition, they do not guarantee that the order of elements will not change over time. In turn, TreeMapit guarantees the storage of elements in the order they were added or in accordance with a given comparator.

  2. Valid values. HashMapallows you to have a key and a null value, HashTableno. TreeMap can only use null values ​​if the comparator allows it. Without using a comparator (by storing pairs in the order they were added), null is not allowed.

  3. Synchronization. Only HashTablesynchronized, the rest are not. If the map will not be accessed by different threads, it is recommended to use HashMap instead of HashTable.

And a general comparison of implementations:
HashMap HashTable TreeMap
Order of elements No No Yes
null as value Yes No Not really
Thread safety No Yes No
Algorithmic complexity of searching for elements O(1) O(1) O(log n)
Data structure under the hood hash table hash table red-black tree

5. How to create a bidirectional map

Sometimes it becomes necessary to use a data structure in which both keys and values ​​will be unique, that is, the map will contain key-key pairs. This data structure allows you to create an “inverted view/search” on the map. That is, we can find a key by its value. This data structure is called a bidirectional map, which, unfortunately, is not supported by the JDK. But, fortunately, its implementation can be found in the Apache Common Collections or Guava libraries. There it is called BidiMap and BiMap, respectively. These implementations impose restrictions on the uniqueness of keys and values. This creates a one-to-one relationship.

6. How to create an empty Map

There are two ways to create an empty map:
  1. Normal object initialization:

    Map<Integer, String> emptyMap = new HashMap<>();
  2. Creating an immutable empty map:

    Map<Integer, String> emptyMap =  Collections.emptyMap();
When we try to add data to such a map, we will receive: UnsupportedOperationExceptionexception. In this article, we looked at the most common questions that you might have when using the Map interface.
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION