This question already has an answer here:
why the output of the Hashmap is arbitary, not in a specific order? why its sorting order gets change on insertion & deletion of new node?
(1 answer)
Closed 8 years ago.
Items displayed as unsorted
map.put("California", "Sacramento");
map.put("Oregon", "Salem");
map.put("Washington", "Olympia");
System.out.println(map);
map.put("Alaska", "Juneau");
System.out.println(map);
HashMaps in java aren't sorted!
HashMap makes absolutely no guarantees about the iteration order. It
can (and will) even change completely when new elements are added.
TreeMap will iterate according to the "natural ordering" of the keys
according to their compareTo() method (or an externally supplied
Comparator). Additionally, it implements the SortedMap interface,
which contains methods that depend on this sort order.
LinkedHashMap will iterate in the order in which the entries were put
into the map
I try it, my print is :
{California=Sacramento, Oregon=Salem, Washington=Olympia}
{California=Sacramento, Oregon=Salem, Washington=Olympia, Alaska=Juneau}
Alaska=Juneau is displayed at the end.
but TreeMap is order.print:
{Alaska=Juneau, California=Sacramento, Oregon=Salem, Washington=Olympia}
Related
I am a beginner in Java. Please explain it as plain as possible.
I am putting a dummy code, because this site didn't let me post the question without this:
public void printSorted(PrintStream out) {
TreeMap<Integer,String> map2 = new TreeMap<Integer,String>();
for(Map.Entry<String,Integer> entry : concord.entrySet()){
map2.put(entry.getValue(), entry.getKey());
}//NavigableMap nmap=treemap.descendingMap();
for(Map.Entry<Integer,String> entry2 : map2.descendingMap().entrySet()){
System.out.println(entry2.getValue()+ " " + entry2.getKey());
}
}
Why can't we just use its iterator or a for-each loop to visit the values in a java Map(HashMap or TreeMap) in order?
Because those two classes do not maintain the values in any order. (Apart from the implied order of the keys ... in the TreeMap case.)
Indeed, there is not even a requirement on the value type of a Map that it be orderable.
If you want / need the values of a map in order:
If the ordering you want is "entry insertion order" or "entry least recently used", then use a LinkedHashMap.
For other orderings, you can copy the list of values (or the set of entries) into a separate set and then sort it. (Or you can do the equivalent with streams without an explicit copy.) But the point is that the Map itself won't / can't maintain the ordering you have just created by sorting.
If you want to avoid the cost of repeated sorting, use a separate (incrementally updatable) data structure to keep a sorted list or set of the values.
P.S. If you actually are asking about iterating the keys or entries in order, then TreeMap already does that. And ...
why do we use Map iterator and not use for/each loop?
We can do either. Both work. And indeed, a for each loop uses the Iterator under the covers.
You only need to use an iterator explicitly if you want to explicitly call methods on the iterator; e.g. Iterator::remove()
This question already has answers here:
is collections.sort method only used for List type of collections?
(7 answers)
Closed 6 years ago.
Why can't I Collections.sort my Set<MyType>? My code is below. When I use an ArrayListthis code works perfectly, but when I use any kind of Set, I get this error.
Set<Auto> set = new HashSet<Auto>();
set.add(auto1);
set.add(auto2);
set.add(auto3);
set.add(auto4);
set.add(auto5);
Collections.sort(set, new Comparator<Auto>() {
#Override
public int compare(Auto o1, Auto o2) {
return o1.getMarka().compareTo(o2.getMarka());
}
});
HashSet is not an ordered collection; in other words, it does not contain elements in a certain order.
You can see a HashSet as a bag that contains objects. When you stick your hand in and pull out objects one by one, you don't know in what order you get elements out. You can't sort elements in the bag - because the bag doesn't keep them in the order that you sorted them in.
The order of elements is lost; so sorting a HashSet has no effect (besides the fact that Collections.sort takes a List instead of a Set as Mureinik noticed, so your code doesn't even compile).
If you need the elements in the Set to be in a specific, defined order, then use a different Set implementation, for example TreeSet.
Sets don't have an order, so you cannot order them. As seen in the Javadoc, Collections#sort receives a List, not any Collection.
This question already has answers here:
Ordering of elements in Java HashSet
(2 answers)
Closed 8 years ago.
this is my code on one exercise,
public class RockTest {
public static void main(String[] args){
HashSet<Rock> hashset = new HashSet();
Rock rock1 = new Rock("QingDanasty",89);
Rock rock2 = new Rock("Modern",32);
Rock rock3 = new Rock("MingDanasty",100);
hashset.add(rock1);
hashset.add(rock2);
hashset.add(rock3);
Iterator<Rock> iterator = hashset.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next().getName());
}
}
}
When the code gets printed, the console shows the order of rock2 rock1 rock3 instead of rock1 rock2 and rock3 ,however, I wonder why?
HashSet doesn't preserve order, if you want it to preserve order of insertion use LinkedHashSet instead
if you want it to preserve some comparative order then use custom Comparator and TreeSet
HashSet is not an OrderedSet like for example TreeSet, therefore you can't make any assumptions on the order.
HashSet not grantee the insertion order. you can use TreeSet or LinkHashSet if you are concern about the insertion order.
As the other answers have pointed out, it is because you are using a Set to store your objects (in your case a HashSet in particular). Sets do not guarantee ordering of items added to them, this is why you see them printed out in a different order to how you added them. If you want to maintain ordering of elements added to a Collection, then you probably need to use a List such as LinkedList or ArrayList.
Rather than just leaving you at that, I'll point you in the direction of the Java trail on the different Collection types within the language. What the trail will help you understand is when to use the different types of Collection implementation that Java provides and what are the characteristics of each collection type.
For a HashSet, iteration order is based on the hashCode of each element, which is more or less "random" (although determinant for instances of some classes).
To have iteration order match the insertion order, use a LinkedHashSet whose iteration order is the same as insertion order, or an implementation of SortedSet such as TreeSet, which sorts its elements based on their natural order (if they inplement Comparable) or using a supplied Comparator.
This question already has answers here:
How to avoid items being re-ordered when put into java HashMap
(4 answers)
Closed 8 years ago.
HashMap<Integer, String> map = new HashMap<Integer, String>();
map.put(5,a);
map.put(4,b);
map.put(3,c);
map.put(2,d);
map.put(1,e);
System.out.println(map);
Why the result is equal {1=e, 2=d, 3=c, 4=b, 5=a}?
Java HashMap doesn't keep any order. API says
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.
From HashMap's javadoc:
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 LinkedHashMap would suffice for ordering by insertion order, and a TreeMap may be used when order through a key's comparator is needed.
This question already has answers here:
Is the order of values retrieved from a HashMap the insertion order
(6 answers)
Closed 9 years ago.
I have a Map with values and get a Set using Map.keySet method.
In this code:
Map<String, String> map = new HashMap<>();
map.put("1", "a");
map.put("2", "b");
map.put("3", "c");
Set<String> set = map.keySet();
for (int i = 0; i < 5; i++) {
for (String key : set) {
System.out.println(key);
}
}
am I guaranteed to get
1
2
3
written out every time? Where is this guarantee written down ? In Javadoc?
EDIT: Actually I don't care about the insertion order, but I care about the fact that using for-each loop on a set will produce the same result over and over, providing that the undelying map does not change (I don't call put, remove).
No, you are not. But you can use LinkedHashMap (http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html) and then you will be guaranteed.
LinkedHashMap for order of additionn (put), and TreeMap (interface SortedMap) for order of keys.
Unfortunately the docs for HashMap state that keySet() method does not return a SortedSet, it just returns a Set, for which the ordering is not guaranteed.
See HashMap.keySet()
Read, in particular: 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.
Use LinkedHashMap if you want to retrieve in order in which you put key .
No you're not guaranteed a specific order, unless you use a HashMap which implements a custom set that can give you this guarantee. The Set the HashMap gives you back have an Iterator() method which iterates over the elements in "no particular order".
Read the java documentation: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Set.html#iterator()
If you want the guarantee that the elements are iterated over in-order, i.e. ascending order, use something that implements SortedMap like TreeMap.
TreeMap Documentation: http://docs.oracle.com/javase/6/docs/api/java/util/TreeMap.html
On this page you find the getSet() method which says "The set's iterator returns the keys in ascending order".