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 theentrySet()
. 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.
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:-
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));
-
Use
SortedMap
, or more precisely, its implementationTreeMap
, 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 interfaceComparable
: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:-
Order of elements.
HashMap
andHashtable
do 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,TreeMap
it guarantees the storage of elements in the order they were added or in accordance with a given comparator. -
Valid values.
HashMap
allows you to have a key and a null value,HashTable
no. 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. -
Synchronization. Only
HashTable
synchronized, the rest are not. If the map will not be accessed by different threads, it is recommended to use HashMap instead of HashTable.
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:-
Normal object initialization:
Map<Integer, String> emptyMap = new HashMap<>();
-
Creating an immutable empty map:
Map<Integer, String> emptyMap = Collections.emptyMap();
UnsupportedOperationException
exception. In this article, we looked at the most common questions that you might have when using the Map interface.
What else to read: |
---|
GO TO FULL VERSION