What is the difference between a HashMap and a TreeMap? [duplicate] - java

This question already has answers here:
Difference between HashMap, LinkedHashMap and TreeMap
(17 answers)
Closed 8 years ago.
I started learning Java. When would I use a HashMap over a TreeMap?

TreeMap is an example of a SortedMap, which means that the order of the keys can be sorted, and when iterating over the keys, you can expect that they will be in order.
HashMap on the other hand, makes no such guarantee. Therefore, when iterating over the keys of a HashMap, you can't be sure what order they will be in.
HashMap will be more efficient in general, so use it whenever you don't care about the order of the keys.

HashMap is implemented by Hash Table while TreeMap is implemented by Red-Black tree. The main difference between HashMap and TreeMap actually reflect the main difference between a Hash and a Binary Tree , that is, when iterating, TreeMap guarantee can the key order which is determined by either element's compareTo() method or a comparator set in the TreeMap's constructor.
Take a look at following diagram.

To sum up:
HashMap: Lookup-array structure, based on hashCode(), equals() implementations, O(1) runtime complexity for inserting and searching, unsorted
TreeMap: Tree structure, based on compareTo() implementation, O(log(N)) runtime complexity for inserting and searching, sorted
Taken from: HashMap vs. TreeMap

Use HashMap most of the times but use TreeMap when you need the key to be sorted (when you need to iterate the keys).

I'll talk about the HashMap and TreeMap implementation in Java:
HashMap -- implement basic map interface
implemented by an array of buckets, each bucket is a LinkedList of entries
running time of basic operations: put(), average O(1), worst case O(n), happens when the table is resized; get(), remove(), average O(1)
not synchronized, to synchronize it: Map m = Collections.synchronizedMap(new HashMap(...));
Iteration order of the map is unpredictable.
TreeMap -- implement navigable map interface
implemented by a red-black tree
running time of basic operations: put(), get(), remove(), worst case O(lgn)
not synchronized, to synchronize it: SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));
provide ordered iteration. higherKey(), lowerKey() can be used to get the successor and predecessor of a given key.
To sum, the biggest difference between HashMap and TreeMap is that TreeMap implements NavigableMap<K,V>, which provide the feature of ordered iteration. Besides, both HashMap and TreeMap are members of Java Collection framework. You can investigate the source code of Java to know more about their implementations.

You almost always use HashMap, you should only use TreeMap if you need your keys to be in a specific order.

HashMap is used for fast lookup, whereas TreeMap is used for sorted iterations over the map.

Along with sorted key store one another difference is with TreeMap, developer can give (String.CASE_INSENSITIVE_ORDER) with String keys, so then the comparator ignores case of key while performing comparison of keys on map access. This is not possible to give such option with HashMap - it is always case sensitive comparisons in HashMap.

Related

What is increased cost of TreeSet vs LinkedHashSet and TreeMap over LinkedHashMap?

LinkedHashSet - This implementation spares its clients from the unspecified, generally chaotic ordering provided by HashSet, without incurring the increased cost associated with TreeSet.
Same is said about LinkedHashMap vs TreeMap
What is this increased cost (LinkedHashMap vs TreeMap) exactly?
Does that mean that TreeSet needs more memory per element? LinkedHashSet needs more memory for two additional links, but TreeSet needs additional memory to store Map.Entry pair of elements (because implicitly based on TreeMap), besides LinkedHashSet is based on HashMap which also has Map.Entry pair of elements overhead...
So the difference is how fast a new element is added (in case of TreeSet it takes longer due to some "sorting").
What are other significant increased costs?
TreeSet/TreeMap have a higher time complexity for operations such ass add(), contains() (for TreeSet), put(), containsKey() (for TreeMap), etc... since they require logarithmic time to locate elements in the tree (or add elements to the tree), while LinkedHashSet/LinkedHashMap require expected constant time for those operations.
In terms of memory requirements, there's a very small difference:
TreeMap entries hold key, value, 3 Entry references (left, right, parent) and a boolean.
LinkedHashMap entries hold key, value, 3 Entry references (next, before, after) and an int.
When iterating a HashSet, the iteration order is generally the order of the hash of the object, which is generally not too useful if you want a predictable order.
If sane ordering is important you would generally need to use a TreeSet which iterates in sorted order but at a cost because maintaining the sorted order adds to the complexity of the process.
A LinkedHashSet can be used as a middle-ground solution to the seemingly insane ordering of a HashSet by ensuring that the iteration order is at least consistent by using the insertion order.

Why do we need hashcode and bucket in LinkedHashMap

Lately,I've been going through implementations of Map interface in java. I understood HashMap and everything made sense.
But when it comes to LinkedHashMap, as per my knowledge so far, the Entry has key, value, before and after. where before and after keeps track of order of insertion.
However, using hashcode and bucket concept doesn't make sense to me in LinkedHashMaps.
I went through this article for understanding implementation of linkedHashMaps
Could someone please explain it? I mean why does it matter in which bucket we put the entry node. In fact why bucket concept in the first place.? why not plain doubly llinked lists?
LinkedHashMap is still a type of a HashMap. It uses the same logic as HashMap in order to find the bucket where a key belongs (used in methods such as get(),put(),containsKey(),etc...). The hashCode() is used to locate that bucket. This logic is essential for the expected O(1) performance of these operations.
The added functionality of LinkedHashMap (which uses the before and after references) is only used to iterate the entries according to insertion order, so it affects the iterators of the Collections returned by the keySet(),entrySet() & values() methods. It doesn't affect where the entries are stored.
Without hashcodes and buckets, LinkedHashMap won't be able to lookup keys in the Map in O(1) expected time.

ArrayList to HashMaps in Java

I am trying to get values from an ArrayList that is sorted and want to store it in a HashMap, where the values of the ArrayList become keys of the HashMap. Will the order of the values in the HashMap still be the same as that of ArrayList?
No. Use a TreeMap instead. This will preserve the order of insertion.
HashMap makes no guarantees as to the order the mappings are stored or iterated, so simply running through the ArrayList and putting them into the HashMap as keys will very likely result in unordered iterations.
As others have pointed out, LinkedHashMap does preserve insertion order for iterations. An additional run of insertions will result in unordered iterations again, though. Both HashMap and LinkedHashMap support constant time lookup - LinkedHashMap pays for its extra feature in space (by maintaining pointers between the keys).
As others have also pointed out, TreeMap preserves order after updates, so this might be a better option for you, or not. Of course, if the ArrayList is sorted with a specific Comparator, you must feed that same Comparator to the TreeMap on construction for the sorting to be the same. Note that TreeMap does not have constant time lookup, due to being implemented as a Red-Black search tree.
As your ArrayList has been ordered, no need to use a TreeMap because this will compare to order again and it's not necessary. You should use a LinkedHashMap that will keep the exact order of your ArrayList when you put your value in.
Check This: Insert Values of ArrayList into HashMap
HashMap<String, Item> itemMap = new HashMap<String, Item>();
for (Item item : itemList)
{
itemMap.put(item.getitemCode(), item);
}

Map - Fixed iteration order

Can we get data from a Map in some sequence or ordering which will be fixed for every time in Java?
Well in some maps you can. For example, any implementation of SortedMap (e.g. TreeMap) will return the entries sorted by key order (possibly according to a custom comparator) - although that has implications on the complexity of adding and fetching entries, of course.
Then there's LinkedHashMap which will always return entries in insertion order.
If you're talking about plain HashMap though - no, you mustn't rely on the ordering.
You can use the LinkedHashMap which is an ordered implementation of the Map interface.

How does Java order items in a HashMap or a HashTable?

I was wondering how Java orders items in the Map (HashMap or Hashtable) when they are added. Are the keys ordered by the hashcode, memory reference or by allocation precedence...?
It's because I've noticed same pairs in the Map are not always in the same order
java.util.HashMap is unordered; you can't and shouldn't assume anything beyond 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.
java.util.LinkedHashMap uses insertion-order.
This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).
java.util.TreeMap, a SortedMap, uses either natural or custom ordering of the keys.
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.
First of all: HashMap specifically doesn't provide a stable and/or defined ordering. So anything you observe is simply an implementation detail and you must not depend on it in any way.
Since it is sometimes useful to know the reason for the seemingly random ordering, here's the basic idea:
A HashMap has number of buckets (implemented as an array) in which to store entries.
When an item is added to the map, it is assigned to a buckets based on a value derived of its hashCode and the bucket size of the HashMap. (Note that it's possible that the bucket is already occupied, which is called a collision. That's handled gracefully and correctly, but I'll ignore that handling for the description because it doesn't change the concept).
The perceived ordering of the entires (such as returned by iterating over the Map) depends on the order of the entries in those buckets.
Whenever the size is rehashed (because the map exceeded its fullness threshold), then the number of buckets changes, which means that the position of each element might change, since the bucket position is derived from the number of buckets as well.
HashMap does not sort at all. For a map that sorts by key values you should use TreeMap instead.
From the JavaDocs for TreeMap:
Red-Black tree based implementation of
the SortedMap interface. This class
guarantees that the map will be in
ascending key order, sorted according
to the natural order for the key's
class (see Comparable), or by the
comparator provided at creation time,
depending on which constructor is
used.
From the documentation of HashMap:
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.
A Map is not an ordered data structure - you should not rely on entries in a HashMap being in a certain order. Some Map implementations such as LinkedHashMap and TreeMap do guarantee a certain order, but HashMap does not.
If you really want to know what happens internally, lookup the source code of HashMap - you can find it in src.zip which should be in your JDK installation directory.
A HashMap has a number of "buckets" in which it stores its entries. Which bucket an entry is stored in is determined by the hash code of the key of the entry. The order in which you see the entries in the HashMap depends on the hash codes of the keys. But don't write programs that rely on entries being in a certain order in a HashMap - the implementation might change in a future version of Java and your program then would not work anymore.
hashmap has a not defined order of the elements
There is no defined ordering in a hash table. Keys are placed into a slot, based on the hash code, but even that isn't a trivial order-by-hash-code.
HashMap stores the values using the unique hash-value generated using a part of the key. This hash-value maps to the address where it is going to be stored. This is how it ensures an access O(1).
LinkedHashmap on the other hand preserves the order in which you added to the map.

Categories

Resources