This question already has answers here:
The built-in iterator for java's PriorityQueue does not traverse the data structure in any particular order. Why?
(5 answers)
Closed 6 years ago.
I was learning Java and trying to learn priority queue in collections. I tried with below example from one website:
import java.util.*;
class S
{
public static void main(String args[])
{
PriorityQueue<String> queue=new PriorityQueue<String>();
queue.add("Amit");
queue.add("Vijay");
queue.add("Karan");
queue.add("Rahul");
queue.add("Jai");
System.out.println("iterating the queue elements:");
Iterator<String> itr=queue.iterator();
while(itr.hasNext())
{
System.out.println(itr.next());
}
}
}
here results came is below:
Amit
Jai
Karan
Vijay
Rahul`
I was expecting the result as :
Amit
Vijay
Karan
Rahul
Jai
I am not able to understand how the result changes from my expectation and what type of normal or default priority is used.
In case i want to get the same result as per my expectation, what should i do using prioiryqueue?
Please help me.
Here i want the exact cause of default ordering in priority queue.
Quoting javadoc of PriorityQueue:
The Iterator provided in method iterator() is not guaranteed to traverse the elements of the priority queue in any particular order.
As you can see, the ordering of the PriorityQueue doesn't matter when using iterator(). Now if you began to take values from the queue using poll(), you would get the values in lexicographical order, i.e. the natural order of String.
If you want a queue that returns items in insertion order, use a regular Queue implementation like LinkedList or ArrayDeque.
Related
This question already has answers here:
How to iterate over a PriorityQueue?
(10 answers)
Closed 3 years ago.
I have configuration-elements put into a PriorityQueue. I am accessing the elements via
for (Element e : queue) {
...
}
This works well enough but after putting an additional configuration element into the queue, the ordering is disrupted. Even stranger, it depends on the sequence in which I enter the elements into the queue, whether sorting is correct or not.
Javadoc of PriorityQueue states
The Iterator is not guaranteed to traverse the elements of the priority queue in any particular order.
basically, a PriorityQueue cannot be used in a for-each construct if ordering is required.
Depending on the code in question, either use iterated queue.poll() calls or switch to another datastructure like List and sort this exlipcitly via Collections.sort().
As with the ordering being correct sometimes: You just got lucky at first.
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.
I know, queue follow FIFO(First in first out) order, but I am not sure why the following output appears with below java sample program
JAVA Sample
public static void main(String args[]) {
Queue<String> q = new PriorityQueue<String>();
q.add("3");
q.add("1");
q.add("2");
Iterator<String> itr = q.iterator();
while (itr.hasNext()) {
System.out.println(itr.next() + " ");
}
}
OUTPUT :
1
3
2
As per Java doc of java.util.PriorityQueue.PriorityQueue()
Creates a PriorityQueue with the default initial capacity (11) that orders its elements according to their natural ordering.
Q1) Could any body please explain why the output is 1 3 2 and how
the natural order works here.
Q2) I have checked about natural ordering and its related to the
Comparable/Comparor but doesn't they are for
Sorting(Ascending/Descending) Order only??
The PriorityQueue in Java is a datastructure, that sorts the elements it contains. Excerpt from the Javadoc:
The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.
The Problem with the unordered output comes from the iterator implementation. Another excerpt, this time from the iterator() method:
Returns an iterator over the elements in this queue. The iterator does not return the elements in any particular order.
So you don't java a fixed order with the iterator. If you use the poll() method in a loop you would get all given elements in ascending order.
If you are looking for a Queue in the FIFO-sense you may have a look at the LinkedList and only use the addFirst() and getLast() methods.
This question already has answers here:
Java List Sorting: Is there a way to keep a list permantly sorted automatically like TreeMap?
(17 answers)
Closed 4 years ago.
Do we have sorted list in java just like SortedSet or TreeMap ? I have a class having one of the property as List of objects. This list has to be sorted at any time when adding or when setting it through setters (set(List list)).
Do we have any component like TreeMap for list ? Any suggestions or help will be really appreciable. Thanks in advance.
The purpose of having a list is that they should maintain the order of the elements in which they were added. So, I believe there is no such List implementation in which the elements are sorted as they are added.
You can use Collections.sort() method to sort the list any time.
What you want is a sorted Bag/MultiSet implementation, like Google Guava's TreeMultiSet ?
A TreeMultiSet in Guava is defined as:
A multiset which maintains the ordering of its elements, according to
either their natural order or an explicit Comparator.
Where a MultiSet is:
A collection that supports order-independent equality, like Set, but
may have duplicate elements. A multiset is also sometimes called a
bag.
For more information about MultiSets, you can read this dzone article on Google Guava: MultiSets (except in your case you really want the TreeMultiSet), and this page of the Guava wiki explaining their new collection types.
You may use some other data type for your Collection since you do not care about the order of elements (which is an essential property of a List). For example I think that SortedSet can do the trick if you don't have duplicates.
Otherwise you can use Collections.sort() on your List.
You can extends existing ArrayList To create a SortedList. As you will only have to take care of order while insertion.
public class SortedList<E extends Comparable<E>> extends ArrayList<E> {
#Override
public boolean add(E e) {
int index = Collections.binarySearch(this, e);
super.add(index < 0 ? ~index : index, e);
return true;
};
}
Java Doc Collections.binarySearch
Returns: the index of the search key, if it is contained in the list; otherwise, (-(insertion point) - 1). The insertion point is defined as the point at which the key would be inserted into the list: the index of the first element greater than the key, or list.size() if all elements in the list are less than the specified key. Note that this guarantees that the return value will be >= 0 if and only if the key is found.
Update:
As #Louis Wasserman has pointed out this create problems with basic list contract that is insert elements based on index. If you want to support that functionality then you should use Collections.sort(). You can also use org.apache.commons.collections.list.TreeList which has below relative performance statistics to that class
get add insert iterate remove
TreeList 3 5 1 2 1
ArrayList 1 1 40 1 40
LinkedList 5800 1 350 2 325
The Java SDK doesn't have a sorted List class. The easiest solution for what you need would be to call Collections.sort() on your List every time you add something to it.
This question already has answers here:
The built-in iterator for java's PriorityQueue does not traverse the data structure in any particular order. Why?
(5 answers)
Closed 7 years ago.
I am trying to use priority queue to keep an ordered list of integers. in a simple exaple like this:
PriorityQueue<Integer> queue = new PriorityQueue<>();
queue.offer(3000);
queue.offer(1999);
queue.offer(999);
for(Integer i : queue)
System.out.println(i);
This prints
999
3000
1999
This is not what I am expecting considering natural odering.
I simply want to iterate without removing or adding through the queue (which serves as a sorted list) WITH ordering. Can I still do that in a simple manner?
PriorityQueue is a collection optimized for finding the tail or head value quickly, using a partially ordered tree structure called heap (look it up on wikipedia). If you pop the elements, they will be ordered. If you want to iterate, use for example a SortedSet instead, which also stores the elements sorted.
This is a very sneaky problem with PriorityQueue: to quote the Api
The Iterator provided in method iterator() is not guaranteed to
traverse the elements of the priority queue in any particular order.
If you need ordered traversal, consider using
Arrays.sort(pq.toArray()).
Use Poll instead to get the head which will be in order