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

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.

Related

Iteration Order of HashMap key same or not

I want to know that HashMap is give same sequence of key when iterated each time after adding records.
I am using following code
HashMap<String,String> mapObj=new HashMap<String,String>();
mapObj.put("a", "aValue");
mapObj.put("b", "bValue");
mapObj.put("c", "cValue");
for(String key:mapObj.keySet()){
System.out.println(key+" :: "+mapObj.get(key));
}
for(String key:mapObj.keySet()){
System.out.println(key+" :: "+mapObj.get(key));
}
output of following program is
b :: bValue
c :: cValue
a :: aValue
b :: bValue
c :: cValue
a :: aValue
If you don't make any changes to the HashMap between the two iterations, you'll likely see the same iteration order (even though it's not guaranteed), since this is a deterministic data structure. However, adding or removing entries between the two iterations will probably change the iteration order.
If you want to rely on the iteration order, use LinkedHashMap, in which (by default) the keys are iterated in the order they were first added to the Map.
If you want to iterate over the keys in some specific order, you can use TreeMap instead (where the keys are ordered according to their natural ordering or the supplied Comparator).
Hash map accept the object to be stored as an argument and
generate a number that is unique to it.
HashMap uses hashing to store the entries in hashmap, so there is no gurantee those will appear in specific order. If you want your entries from your HashMap ordered, then you will have to sort it or you can use Treemap
HashMap doesn't maintain the order. If you want your elements to be retrieved in order then better to use LinkedHashMap.
Generally it would be little surprising if the iteration order changed for multiple subsequent invocations (assuming the map itself did not change in between). BUT you should not rely on it as API does not make any guarantee for that.
As per doc:
The Map interface provides three collection views, which allow a map's
contents to be viewed as a set of keys, collection of values, or set
of key-value mappings. The order of a map is defined as the order in
which the iterators on the map's collection views return their
elements. Some map implementations, like the TreeMap class, make
specific guarantees as to their order; others, like the HashMap
class, do not.
You can use LinkedHashMap as its entrySetmaintain insertion ordering, as per Java Doc:
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).
TreeMap maintain the natural ordering of keys.
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.

Why don't TreeMap.values() reflect the order in which elements were originally added?

I need a data structure that will perform both the role of a lookup map by key as well as be able to be convertable into a sorted list. The data that goes in is a very siple code-description pair (e.g. M/Married, D/Divorced etc). The lookup requirement is in order to get the description once the user makes a selection in the UI, whose value is the code. The sorted list requirement is in order to feed the data into UI components (JSF) which take List as input and the values always need to be displayed in the same order (alphabetical order of description).
The first thing that came to mind was a TreeMap. So I retrieve the data from my DB in the order I want it to be shown in the UI and load it into my tree map, keyed by the code so that I can later look up descriptions for further display once the user makes selections. As for getting a sorted list out of that same map, as per this post, I am doing the following:
List<CodeObject> list = new ArrayList<CodeObject>(map.values());
However, the list is not sorted in the same order that they were put into the map. The map is declared as a SortedMap and implemented as a TreeMap:
SortedMap<String, CodeObject> map = new TreeMap<String, CodeObject>().
CodeObject is a simple POJO containing just the code and description and corresponding getters (setters in through the constructor), a list of which is fed to UI components, which use the code as the value and description for display. I used to use just a List and that work fine with respect to ordering but a List does not provide an efficient interface for looking up a value by key and I now do have that requirement.
So, my questions are:
If TreeMap is supposed to be a map in the ordered of item addition, why isn's TreeMap.values() in the same order?
What should I do to fulfill my requirements explained above, i.e. have a data structure that will serve as both a lookup map AND a sorted collection of elements? Will TreeMap do it for me if I use it differently or do I need an altogether different approach?
TreeMap maintain's the key's natural order. You can even order it (with a bit more manipulation and custom definition of a comparator) by the natural order/reverse order of the value. But this is not the same as saying "Insertion order". To maintain the insertion order you need to use LinkedHashMap. Java LinkedHashMap is a subclass of HashMap - the analogy is the same as LinkedList where you maintain the trace of the next node. However, it says it cannot "Guarantee" that the order is maintained, so don't ask your money back if you suddenly see an insertion order is maintained with HashMap
TreeMap's documentation 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.
So unless you're providing a Comparator and tracking the insertion order and using it in that Comparator, you'll get the natural order of the keys, not the order in which the keys were inserted.
If you want insertion order, as davide said, you can use LinkedHashMap:
Hash table and linked list implementation of the Map interface, with predictable iteration order...This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). Note that insertion order is not affected if a key is re-inserted into the map.
What you need is LinkedHashMap
See another question as well.

Map implementation that keeps entries in the order of addition

I need a key-value pair data structure which guarantees the retrieval of entries in the order in which they were added, much like ArrayList or Vector for just singular entries. Think of it as an ArrayList that enables key-value pairs. Keep in mind, the TreeMap will not do because the sorting does not go by the value of the key but by the time of insertion. Is there a Java Collection that meets these requirements? I browsed different Map implementations but couldn't find any that match.
I understand I can define my class that takes the key and the value and put it in an ArrayList but that is only option B to a class described above.
Are you looking for LinkedHashMap ?
Hash table and linked list implementation of the Map interface, with predictable iteration order.
You can also look into the Guava's ImmutableMap if it suits your purpose.
An immutable, hash-based Map with reliable user-specified iteration order. Does not permit null keys or values.
I need a key-value pair data structure which guarantees the retrieval of entries in the order in which they were added,
LinkedHashMap
Hash table and linked list implementation of the Map interface, with predictable iteration order.
Use java.util.LinkedHashMap Javadocs here
"This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order)"

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 the order guaranteed for the return of keys and values from a LinkedHashMap object?

I know LinkedHashMap has a predictable iteration order (insertion order). Does the Set returned by LinkedHashMap.keySet() and the Collection returned by LinkedHashMap.values() also maintain this order?
The Map interface provides three
collection views, which allow a map's contents to be viewed as a set
of keys, collection of values, or set
of key-value mappings. The order of
a map is defined as the order in which
the iterators on the map's collection
views return their elements. Some map
implementations, like the TreeMap
class, make specific guarantees as to
their order; others, like the
HashMap class, do not.
-- Map
This linked list defines the iteration
ordering, which is normally the order
in which keys were inserted into the
map (insertion-order).
-- LinkedHashMap
So, yes, keySet(), values(), and entrySet() (the three collection views mentioned) return values in the order the internal linked list uses. And yes, the JavaDoc for Map and LinkedHashMap guarantee it.
That is the point of this class, after all.
Looking at the source, it looks like it does. keySet(), values(), and entrySet() all use the same entry iterator internally.
Don't get confused with LinkedHashMap.keySet() and LinkedHashMap.entrySet() returning Set and hence it should not guarantee ordering !
Set is an interface with HashSet,TreeSet etc beings its implementations. The HashSet implementation of Set interface does not guarantees ordering. But TreeSet does. Also LinkedHashSet does.
Therefore it depends on how Set has been implemented in LinkedHashMap to know whether the returning Set reference will guarantee ordering or not.
I went through the source code of LinkedHashMap, it looks like this:
private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}
Thus LinkedHashMap/HashMap has its own implementation of Set i.e. KeySet. Thus don't confuse this with HashSet.
Also, the order is maintained by how the elements are inserted into the bucket. Look at the addEntry(..) method of LinkedHashMap and compare it with that of HashMap which highlights the main difference between HashMap and LinkedHashMap.
You can assume so. The Javadoc says 'predictable iteration order', and the only iterators available in a Map are those for the keySet(), entrySet(), and values().
So in the absence of any further qualification it is clearly intended to apply to all of those iterators.
AFAIK it is not documented so you cannot "formally" assume so. It is unlikely, however, that the current implementation would change.
If you want to ensure order, you may want to iterate over the map entires and insert them into a sorted set with an order function of your choice, though you will be paying a performance cost, naturally.

Categories