I have a hashtable, which contains strings for example, when I use put method as below
hashtable.put("1","A");
hashtable.put("1","B");
hashtable.put("1","C");
hashtable.put("1","D");
hashtable.put("1","E");
Then when I try to print it back it doesn't print in same order, Any one knows why would something like this happen?
Collection c = ht.values();
Iterator itr = c.iterator();
while(itr.hasNext())
System.out.println(itr.next());
Thanks
Max
A Hashtable does not guarantee any kind of ordering.
If you want to preserve insertion order, use a LinkedHashMap. However, the contract is slightly different than a Hashtable in that it allows null elements.
you should use LinkedHashMap if you want to print items in order.
That is simply the property of a hash table -- it makes no guarantee about ordering. Do you want to use a LinkedHashMap instead?
HashTable doesnot keep order.It will print randomly.You should go for LinkedHashMap.You can use LinkedHashMap in the same manner as you did for HashMap.Just put LinkedHashMap in place of HashMap.LinkedHashMap keeps the order of data in which you enter into it.
Related
I have data of which the sequence is as important as its unique elements. Meaning if something has already been added it should not be added again and the sequence must be remembered.
Set does not remember the sequence in which it was added (either hash or sort), and List is not unique.
What is the best solution to this problem?
Should one have a list and loop through it to test for uniqueness - which I'm trying to avoid?
Or should one have two collections, one a List and one a Set - which I'm also trying to avoid?
Or is there a different solution to this problem altogether.
In the bellow code was your reference
LinkedHashSet<String> al=new LinkedHashSet<String>();
al.add("guru");
al.add("karthik");
al.add("raja");
al.add("karthik");
Iterator<String> itr=al.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
output
guru
karthik
raja
Use LinkedHashSet. It serves as both a List and a Set. It has the uniqueness quality of a set but still remembers the order in which you inserted items to it which allows you to iterate it by order of insertion.
From the Docs:
Hash table and linked list implementation of the Set interface, with predictable iteration order. 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. (An element e is reinserted into a set s if s.add(e) is invoked when s.contains(e) would return true immediately prior to the invocation.)
You can use SortedSet
or LinkedHashSet
LinkedHashSet is the best possible way out
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);
}
Code.
Set<String> set = new HashSet<String>(3);
set.add("3 Lorem");
set.add("1 Lorem");
set.add("2 Lorem");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String type = (String) iterator.next();
System.out.println(type);
}
Output.
2 Lorem
3 Lorem
1 Lorem
This order looks strange to me. I add 3 Lorem, 1 Lorem, and then 2 Lorem. Why are they in a different order in the output?
Hash sets are not supposed to be sorted.
Technically they are sorted, but by the hash code (or a hash reduction thereof); and on hash collisions they may overflow into other buckets.
If you want an ordered set, use TreeSet instead. It usually is a bit slower, but sorted. If you want to retain the insertion order, use a List such as ArrayList or LinkedList.
There also is a hybrid, called LinkedHashSet, which allows fast contains operations, but maintains insertion order. Note that it won't have duplicates though.
From the JavaDocs:
This class implements the Set interface, backed by a hash table
(actually a HashMap instance). It makes no guarantees as to the
iteration order of the set; in particular, it does not guarantee that
the order will remain constant over time. This class permits the null
element.
if you intended to keep order better use TreeSet (but complexity will be log(n)
also check this post
Hashset vs Treeset
EDIT as pointed out by #Petar in order to maintain insertion order better use LinkedHashSet
and this Dzone Article demonstrates comparison between all three with nice suit of example and performance
Use a LinkedHashSet to maintain the insertion order.
Use TreeSet<String>(); or TreeSet<String>(String.CASE_INSENSITIVE_ORDER); if you want to Sort the elements. Use List instead of Set If you need to maintain the insertion order.
I have one Map that contains some names and numbers
Map<String,Integer> abc = new HashMap<String,Integer>();
It works fine. I can put some values in it but when I call it in different class it gives me wrong order. For example:
I putted
abc.put("a",1);
abc.put("b",5);
abc.put("c",3);
Iterator<String> iter = abc.keySet().iterator();
while (iter.hasNext()) {
String name = iter.next();
System.out.println(name);
}
some time it returns the order (b,a,c) and some time (a,c,b).
What is wrong with it? Is there any step that I am missing when I call this map?
Edit:
I changed to HashMap and result is still same
The only thing that's wrong is your expectations. The Map interface makes no guarantees about iteration order, and the HashMap implementation is based on hash functions which means the iteration order is basically random, and will sometimes change completely when new elements are added.
If you want a specific iteration order, you have thee options:
The SortedMap interfaces with its TreeMap implementation - these guarantee an iteration order according to the natural ordering of the keys (or an ordering imposed by a Comparator instance)
The LinkedHashMap class iterates in the order the elements were added to the map.
Use a List instead of a Map - this has a well-defined iteration order that you can influence in detail.
I think you need LinkedHashMap.
A TreeMap will always have keys in their natural order (unless you provide a comparator) If you are seeing the order any differently it will be the way you are looking at the map and what you are doing with it. If in doubt, use a debugger and you will see the order is sorted.
If you wish to get map values in the same order you used to insert them use LinkedHashMap instead.
I was working on java HashMaps and found that it adds values to the head of the list. For example ,
hm.put(mike,2);
hm.put(andrew,3);
Now,if i print the hasmap using iterator,i get
andrew 3
mike 2
I want the items to be added in the FIFO fashion rather than LIFO fashion ... Is there a way to do it?
The Map abstraction in Java does not play well with notions of LIFO or FIFO. These concepts primarily apply to ordered sequences, while Maps are stored in an ordering that is entirely independent of the orde in which the values are inserted in order to maximize efficiency. For example, the HashMap uses hashing to store its values, and the more randomly the hash function distributes its values the better the performance. Similarly, the TreeMap uses a balanced binary search tree, which stores its values in sorted order to guarantee fast lookups.
However, Java does have a really cool class called the LinkedHashMap that I believe is exactly what you're looking for. It gives the speed of a HashMap while guaranteeing a predictable traversal order which is defined by the order in which you insert the elements.
Hope this helps!
Try using a LinkedHashMap instead. I don't think HashMaps guarantee order.
LinkedHashMap<String,String> lHashMap = new LinkedHashMap<String,String>();
lHashMap.put("1", "One");
lHashMap.put("2", "Two");
lHashMap.put("3", "Three");
Collection c = lHashMap.values();
Iterator itr = c.iterator();
while (itr.hasNext()){
System.out.println(itr.next());
}
output
One
Two
Three
Do you want to use a Queue?
http://download.oracle.com/javase/6/docs/api/java/util/Queue.html
HashMaps are not ordered, the fact that you are getting them returned from the iterator in the 'wrong' order is just a function of how the hashing is happening on the key.
How specifically do you want to use this datastructure?