java: maps zoo, what to choose - java

I'm pretty new to the Java World (since I'm writing primary in C/C++). I'm using maps in my apps.
Since java.util.Map is abstract I need to instantiate it's implementation. Usually I use HashMap like:
Map<String, MyClass> x = new HashMap<>();
But in java docs I found many other implementations, like TreeMap, LinkedHashMap, HashTable, etc. I want to know if I can continue blindly using of the HashMap or there are any important differences between those Map implementations.
The brief list of points-to-know will be ok.
Thanks.

Never bother with Hashtable, it's a relic from Java 1.0;
HashMap is the universal default due to O(1) lookup and reliance only on equals and hashCode, guaranteed to be implemented for all Java objects;
TreeMap gives you sorted iteration over the map entries (plus a lot more—see NavigableMap), but requires a comparison strategy and has slower insertion and lookup – O(logN) – than HashMap;
LinkedHashMap preserves insertion/access order when iterating over the entries.
SortedMap implementations offer some great features, like headMap and tailMap. NavigableMap implementations offer even more features with terrific performance for operations that assume sorted keys.
Further out there are java.util.concurrent map implementations, like ConcurrentHashMap, which offer great concurrent performance and atomic get/put operations.

HashMap use it almost all the time. Note that your object need have proper implementation of equals and hashCode methods. Does not save insertion order.
HashTable don't use it never.
LinkedHashMap the same as HashMap but saves insertion order. Large overhead.
TreeMap support natural ordering. But insertion works in O(logn).

Hashtable is the thread safe version of HashMap, you shouldn't use it anymore. instead you should use ConcurrentHashMap which is a new implementation of a thread safe map
TreeMap is mostly use when you want to sort your keys, it implements the SortedMap interface. The put/get performance is O(logn).
ConcurrentSkipListMap is used if you need a thread safe SortedMap
LinkedHashMap is used when you want to iterate on keys in the insertion order
I mostly use HashMap or ConcurrentHashMap if I need it to be thread safe

There of course are important differences between each of these maps. It depends purely on what you are trying to do. If you recall a HashMap becomes pretty useless (see inefficient) when you have a poor hashing function in place. The LinkedHashMap is a HashMap that is backed by a doubly linked list, so you can iterate over it. You would eat the overhead that is associated with a linked list of course. TreeMap keeps elements in order, so you will eat that overhead. HashTable is a synchronized collection, that is generally avoided.

are any important differences between those Map implementations
Yes there are some major differences to consider when choosing an implementation of Map.
ConcurrencyWill you be manipulating this map across threads?
NULLsDo you want to accept, or reject, NULL pointers as key and/or value?
SortingDo you want map entries put in some order, such as sorted order or original-insertion order? Do you want support for the SortedMap/NavigableMap interfaces?
Not ModifiableDo you want a map to be frozen, refusing to accept or remove entries?
IdentityDo want to compare keys based on reference-equality or object-equality?
EfficiencyDo you want to take advantage of the very fast performance and very little memory used when your key is an enum?
LiteralsDo you want the convenience of declaring and populating a map in a single line of code?
LegacyDo you want to avoid using a legacy map, created before the modern Java Collections Framework?
Here is a graphic table I made comparing the features of each of the ten Map implementations bundled with Java 11.

Related

Occurred order in the iteration at run-time in a map

In the piece of code similar to
//something before
Iteration<String> iterator = hashMap.keySet().iterator();// HashMap<String, Document>
while(iterator.hasNext()){
System.out.println(iterator.next());
}
//something after
I know that the order of print can be different by the order of insertion of entry key, value; all right.
But if I call this piece in another moment, with re-create the variable hashMap and putting them the equal elements, can the second-moment time print be different from the first-time print?
My question was born by a problem with a web-app: I have a list of String in a JSP, but, after some years, the customer call because the order of the String was different in the morning, but it shows the usual order at the afternoon.
The problem is happened in only one day: the web-app uses the explained piece of code for take a Map and populate an ArrayList.
This ArrayList does'nt any explicit changement of order (no Comparator or similar classes).
I think (hope) that the cause of different order of print derives by a different sequence of iteration in the same HashMap at run-time and I looking for a validation by other people.
In the web, I read that the iteration order by a HashMap changes if the HashMap receives a modification: but what happens if the HashMap remains the same?
Hash map document says HashMap makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
that explains though the hashmap is same it can not guaranatee on order. for Ordered map you can use TreeMap or LinkedHashMap
TreeMap API says The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
HashMap API documentation states that
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
For a Map that keeps its keys in original insertion order, use LinkedHashMap.
For a Map that keeps its keys in sorted order (either natural order or by you passing a Comparator), use either TreeMap or ConcurrentSkipListMap. If multi-threaded, use the second.
For a Map where the key an enum, use EnumMap if you want the entries ordered by the definition order of the enum's objects.
The other six Map implementations bundled with Java 11 do not promise any order to their entries.
See this graphic table of mine as an overview.
Use a LinkedHashMap instead, to preserve insertion order. From the javadoc: "Hash table and linked list implementation of the Map interface, with predictable iteration order."
If you just want a Map with predictable ordering, then you can also use TreeMap. However, a LinkedHashMap is faster, as seen here: "TreeMap has O(log n) performance for containsKey, get, put, and remove, according to the Javadocs, while LinkedHashMap is O(1) for each."
As Octopus mentioned, HashMap "makes no guarantees as to the order of the map," and you shouldn't use it if order must remain consistent.

Sort concurrentHash Map with threadsafty

I am using 'concurrentHashMap' in my 'multithreaded' application. i was able to sort it as describe here. but since i am converting hashmap to a list i am bit worried about the thred safty. My 'ConcurrentHashMap' is a static variable hence i can guarantee there will be only one instance of it. but when i am going to sort it i convert it to a list, and sort then put it back to a new concurrentHashMap.
Is this a good practice in multi-threading enlivenment?
Please let me know your thoughts and suggestions.
Thank you in advance.
You should use a ConcurrentSkipListMap. It is thread-safe, fast and maintains ordering according to the object's comparable implementation.
If you don't change it a lot and all you want is to have it sorted, you should use a TreeMap ** wrapped by a **Collections.synchronizedMap() call
Your code would be something like this:
public class YourClass {
public static final Map<Something,Something> MAP = Collections.synchronizedMap( new TreeMap<Something,Something>() );
}
My 'ConcurrentHashMap' is a static variable hence i can guarantee there will be only one instance of it. but when i am going to sort it i convert it to a list, and sort then put it back to a new concurrentHashMap.
This is not a simple problem.
I can tell you for a fact, that using a ConcurrentHashMap won't make this thread-safe. Nor will using a synchronizedMap wrapper. The problem is that sorting is not supported as a single atomic operation. Rather it involves a sequence of Map API operations, probably with significant time gaps in between them.
I can think of two approaches to solving this:
Avoid the need for sorting in the first place by using a Map that keeps the keys in order; e.g. use ConcurrentSkipListMap.
Wrap the Map class in a custom synchronized wrapper class with a synchronized sort method. The problem with this approach is that you are likely to reintroduce the concurrency bottleneck that you avoided by using ConcurrentHashMap.
And it is worth pointing out that it doesn't make any sense to sort a HashMap or a ConcurrentHashMap because these maps will not preserve the order into which you sort the elements. You could use a LinkedHashMap, which preserves the entry insertion order.

How can I use a Java ConcurrentNavigableMap with comparator instead of a TreeMap?

I need build Queue that will stay allways sorted by its keys .
the TreeMap seams to be great for it like in this example :
http://www.javaexamples4u.com/2009/03/treemap-comparator.html
but the big problem is that its not thread safe , then i found ConcurrentNavigableMap
great , but how do i use the comparator the same way as with the TreeMap? i didn't found any example for it .
It sounds like you are actually looking for a PriorityQueue. If you need a thread-safe version of it, you can use a PriorityBlockingQueue.
A priority queue is a queue where you can retrieve items ordered by "importance." In the case of Java, you can use a Comparator or the items' natural order (if they implement Comparable).
If you really need to use a ConcurrentNavigableMap, you will need to use an implementation of it such as ConcurrentSkipListMap. Just allocate an instance of ConcurrentSkipListMap and pass it the comparator you want to use.
new ConcurrentSkipListMap<MyKeyType, MyValueType>(new MyKeyComparator());
ConcurrentNavigableMap is just the interface. You need to use a concrete class implementing it, which in the standard collections library is ConcurrentSkipListMap.
You should basically be able to use ConcurrentSkipListMap as a drop-in replacement for TreeMap, including using the comparator. Operations will generally have similar performance characteristics (O(log n)), but as I understand the size() operation of ConcurrentSkipListMap requires traversal of the skip list rather than simply reading a variable, so just be slightly careful if you call this frequently on a large map.

what data structure in java suppport sort/order

i use a hashmap to store some data, but i need to keep it in ascending order whenever new data saved to the hashmap or old data move out of the hashmap. but hashmap itself doesn't suppport order, what data structure i can use to support order? Thanks
TreeMap would be the canonical sorted map implementation. Note that this is sorted on the keys, which I presume is what you're after, but if not it won't be suitable.
Since Java 6 also comes with a SortedMap interface, you can look at the list of classes which implement it (on the linked Javadoc page), and choose between those. Implementing this method only guarantees that they have some sort of defined iteration order, you'd have to read the descriptions of each class to see if it's what you like.
TreeMap isn't a hashmap, in that it isn't backed by a hashtable to provide amortised O(1) inserts. However, it's not possible to maintain a sorted map with O(1) inserts anyway (since you have to inspect at least some of the existing elements to work out where the new element should go), and hence the O(lg n) performance of TreeMap is as good as you'll get in this case.
LinkedHashMap may be what you're looking for.
http://download.oracle.com/javase/1.4.2/docs/api/java/util/LinkedHashMap.html

Is there such thing as an ArraySet and ArrayMap?

I would like a map that preserves the order of the elements if there is such a thing.
I am aware that it would not perform near as well as a HashMap, but I only plan to use it for small/temporary programs.
There's no ArrayMap. :)
But a LinkedHashMap will preserve the insertion order, and a TreeMap will order based on the keys' natural ordering.
If you mean a defined ordering of the items you can use a TreeMap (doc here).. otherwise if you are talking about insertion order you can use a LinkedHashMap (doc).
You should check the fastutil project, a memory and time efficient Java Collection framework.
It provides an array map implementation, such as Int2IntArrayMap
Give it a try! I don't use anymore the standard library, fastutils really make the difference.
Hope it helps
There is an ArrayMap in the Android support libraries. There are some non-JDK components, but it shouldn't be that difficult to port.
Source
Have a look at LinkedHashSet and -Map.
This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set.
This implementation spares its clients from the unspecified, generally chaotic ordering provided by HashSet, without incurring the increased cost associated with TreeSet. It can be used to produce a copy of a set that has the same order as the original, regardless of the original set's implementation.
Or how about a ListOrderedMap that retains order of the elements. ListOrderedMap Api

Categories