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
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:
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.
This question already has answers here:
When should I use a TreeMap over a PriorityQueue and vice versa?
(11 answers)
Closed 9 years ago.
I am trying to understand when to use the two data structures. As far as I have understood the PriorityQueue is also implemented as a tree as the documentation states that the average time for insert, remove and contains is O(log(n)). The TreeSet also provides the same time complexity. Plus both of them are unsynchorized implementation. And I can write comparator for them to act like min heap or max heap.
Can some one point out in what conditions I use these two sets?
When you want a queue, use a PriorityQueue. When you want a Set, use a TreeSet. A TreeSet has unique elements, and doesn't offer the API of a Queue. A Queue doesn't offer the API of a Set, and allows multiple equal elements.
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.
I was wondering which Java collection types are traversed fastest. Collections I am most interested in are...
array
LinkedList
Queue
PriorityLinkedList
HashMap
Actually among concrete classes of Collection interface , traversing will be fast through array. Its because as you know it traverse with the index of the element.Since it follows the index pattern so,traversing through index it makes our traversing fast. Why not others? Let me explain one by one..
1.LinkedList : LinkedList follows the insertion order.If you traverse the data and searching for elements,for every element it will search from beginning. So traversing becomes slow.
2.Queue : LinkedList and PriorityQueue are two concrete classes of Queue. 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.It's 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()). So it becomes useless for traversing provided if you traverse without sorting it explicitly.
3.HashMap: If you use Map instead of Collection , traversing is not guaranteed here because it works on hashcode of the key element. So here again traversing becomes useless. You can directly search the element by providing key-value of the element.
4.PriorityLinkedList: This class does not exist in Java APIs.