Sorted Iteration of HashMap Java - java

I know that HashMap is not sorted but is there any away i can create iterator which returns values in sorted order of key. I can use Sorted versions of the collections but I am looking for a way to do the same with Hash Based map.

Any such iterator would have to internally sort all the keys of the HashMap in order to be able to iterate over them in sorted order. It would be more efficient to use an already sorted Map implementation.

You can use TreeMap since its a sorted map.

With Java 8 this is very simple:
import static java.util.Map.Entry.comparingByKey;
public <K extends Comparable<? super K>, V> Iterator<V> orderedIterator(final Map<K, V> map) {
return map.entrySet().stream()
.sorted(comparingByKey())
.map(Map.Entry::getValue)
.iterator();
}
Note, this is slow, as the Stream needs to be sorted each time - so iteration becomes O(n lg n) rather than O(n). If you need to do this a lot, you would be better off using a TreeMap - where insertion is O(lg n) (rather than O(1)) but iteration is still O(n).

I'm not sure this is completely possible, at least from a map point of view, although we could create a special hash map the returns keys from a sort order.
The map could extend HashMap and have a variable the contains the sort order and then have a method that returns the keys and values in the sort order.
You could have a static utility method that takes a HashMap and returns an array of Map.Entrys in the sort order.
While the above may work, TreeMap is probably the way to go. It's designed for this task and was written by Josh Blotch so it's bound to be fast at what it does. Reinventing the wheel always takes longer and doesn't work as well.
Note: This depends on the use case. If you only need to use the sorted values once, then the utility method or custom HashMap implementation will be best. If you're planning on using the Map often, then go with a TreeMap.

Related

A Collection that associates keys to values, and where both a key and a value can be obtained by index

By indexed I mean keys and values can be accessed via an index representing the order in which they were inserted into the collection.
I need a collection that behaves like a Map<K, V>, but also a List<K>(Read-Only) and a List<V>(also Read-Only). My naive implementation is to wrap a HashMap<K, V> and 2 ArrayList, but that leads to massive data redundancy and poor perfomance. Then I thought about LinkedHashMap<K, V>, which would work a lot better in this case, but the getByIndex operations would not perform well, because that would require navigating the internal Linked Nodes, which for small quantities of data is perfectly acceptable, but I'm not exactly sure how will the list be used by client code.
In short, is there something that suits my requirements better than the alternative?
EDIT: If I had something like pointer arithmetics and low level functions like memcpy and a runtime sizeof operator resolving the sizes of K and V, then maybe I could come up with a very efficient implementation. Are there any equivalents to any of that in Java?
I can suggest you few indirect ways.
You can create HashMap < Integer,HashMap< K,V > >. You can insert in this map keeping order as key and then can put the Key-value pair HashMap as value.
You can simply have a single ArrayList<K> and a HashMap<K,V>. For each entry to the map you can insert the key in the array list.
You can use (as you have said in the question itself) LinkedHashMap and can get the iterator or can use for each enhanced for loop for iteration. This way of iterating is efficient and for each step of iteration entire list is not iterated. But you can only iterate and not get the random indexed entry.
If third-party libraries are fair game, Guava's ImmutableMap does this nicely if you don't need mutation. Once it's created, you can use map.entrySet().asList(), map.keySet().asList(), and map.values().asList() to get, in O(1), random-access lists of the entries, keys, and values that support get(index) in O(1).

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.

Why and when to use TreeMap

Could someone tell me when and why to use TREEMAP.I went through This link
but didn't find my answer.
As Per my thinking we use treemap to get the data sort according to your key and the same we can achieve by other ways also.
Let's say you want to implement a dictionary and print it in alphabetical order, you can use a combination of a TreeMap and a TreeSet:
public static void main(String args[]) {
Map<String, Set<String>> dictionary = new TreeMap<>();
Set<String> a = new TreeSet<>(Arrays.asList("Actual", "Arrival", "Actuary"));
Set<String> b = new TreeSet<>(Arrays.asList("Bump", "Bravo", "Basic"));
dictionary.put("B", b);
dictionary.put("A", a);
System.out.println(dictionary);
}
All the sorting is done automatically and it prints:
{A=[Actual, Actuary, Arrival], B=[Basic, Bravo, Bump]}
You could have sorted the structures manually too of course but using TreeMap/Set can be more efficient, reduces the number of lines of code (= the number of bugs) and is more readable.
It is efficient way of having objects sorted by some key. If also random access is important for you then TreeMap is the answer. With this data structure you can iterate in order.
If random access is not needed then rather use sorted set/bag or list.
Why is there no SortedList in Java?
The javadoc you link to, clearly states that it is an implementation of navigable and sorted map interfaces. You would use it when you need this functionality.
TreeMap
A Red-Black tree based NavigableMap implementation. 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.
This implementation provides guaranteed log(n) time cost for the containsKey, get, put and remove operations. Algorithms are adaptations of those in Cormen, Leiserson, and Rivest's Introduction to Algorithms.
Use this data-structure when you need ordered key not only ascending you can pass comparator to constructor TreeMap(Comparator<? super K> comparator) to write your own sorting logic. As well it is a type of self-balancing binary search tree.

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

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.

Categories

Resources