I want to push some int to a priorityqueue but i can't! i used the queue.add() code but this code will return the sorted queue,please help,thank you!
A push/pop operation is clearly defined for a stack abstract data type; I'm not sure if it makes sense for a queue (or even a priority queue).
PriorityQueueimplementsQueue, which only specifies add/remove. On the other hand, a Deque has addFirst/Last, removeFirst/Last, etc. Perhaps one of these is what you're looking for.
An example
Here's an example of using a PriorityQueue of String, using a custom Comparator that compares lengths.
Queue<String> queue = new PriorityQueue<String>(
100, new Comparator<String>() {
#Override public int compare(String s1, String s2) {
return Integer.valueOf(s1.length()).compareTo(s2.length());
}
}
);
queue.add("Sally");
queue.add("Amy");
queue.add("Alice");
System.out.println(queue);
// "[Amy, Sally, Alice]"
System.out.println(queue.remove());
// "Amy"
System.out.println(queue.remove());
// "Alice"
queue.add("Tina");
System.out.println(queue.remove());
// "Tina"
As expected, the PriorityQueue will give the shortest String in the queue upon remove. Also as specified, ties are broken arbitrarily.
Related questions
On PriorityQueue
Java: How do I use a PriorityQueue?
In Java what should I use for a PriorityQueue that returns the greatest element first?
On Comparator and Comparable
When to use Comparable vs Comparator
Java: What is the difference between implementing Comparable and Comparator?
difference between compare() and compareTo()
Comparable and Comparator contract with regards to null
Why does the Java Collections Framework offer two different ways to sort?
The whole point of a priority queue is that it returns the smallest entry (or rather, the first element that'd appear in a sorted list) first. If that's not what you want, you probably don't want a straight PriorityQueue.
What you could do is create a class that has a PriorityQueue for the usual stuff, and a stack for "emergencies". Have a push(T) method that adds stuff to the stack, and an add(T) that adds to the queue. Whatever method gets the next element should remove it from the stack if there's anything there, else it gets the queue's next element.
I want to push some int to a
priorityqueue
'Push' is a stack operation, not a queue operation.
but i can't! i used the
queue.add() code but this code will
return the sorted queue
No it won't. A PriorityQueue is only sorted for the purposes of removing the head of the queue.
Your question doesn't make much sense. If you want to push, use a stack. If you don't want what a PriorityQueue does, don't use it.
What exactly is your actual problem?
Related
I have been investigating the best way to move an ArrayList to a PriorityQueue, and I have found that the best way to do it is by using the method pq.addAll(dataArrayList). But the problem I have now, is how to pass this PriorityQueue, pq, already ordered to the same previous DataArrayList.
The only way I can think of doing it is a structure that runs through the queue, and if the queue is not empty, it extracts and adds in dataArrayList.
public void sort2(Comparator<Router> comp){
PriorityQueue<Router> pq = new PriorityQueue<Router>(comp);
pq.addAll(datos);
datos.clear();
while(!pq.isEmpty()) {
datos.add(pq.poll());
}
}
Router is an ArrayList of Strings(it is actually a class with ip address, city, identifier, but so that we understand each other better we treat it as a String), for example ["a","c","b"] and sort by LessOrder --> ["a","b","c"].
It works, but is it the best way to implement this? Thanks.
I meet a problem about order of PriorityQueue in Java 8, Intellij Idea, when I add the third number in the queue, the order is wrong, but only the third one have this problem, here is my code.
import java.util.*;
public class vector {
static Queue<Integer> q=new PriorityQueue<Integer>();
public static void addNum(int num) {
q.add(num);
}
public static void main(String args[]) {
addNum(-1);
addNum(-2);
addNum(-3);
addNum(-4);
addNum(-5);
}
}
I try to debug the code, after addNum(-3), the queue is -3,-1,-2, but after addNum(-4), the queue is -4, -3, -2, -1.
The contract for PriorityQueue does not guarantee iteration order, but rather it guarantees that each element removed from the priority queue will follow either the natural ordering of the queue's type, or the ordering of a custom comparator, should one be provided.
The Javadoc comments on what you are seeing:
Queues typically, but do not necessarily, order elements in a FIFO (first-in-first-out) manner. Among the exceptions are priority queues, which order elements according to a supplied comparator, or the elements' natural ordering, and LIFO queues (or stacks) which order the elements LIFO (last-in-first-out).
The contract which Java appears to enforce for priority queues is that the first element removed from the queue will follow the natural order of the object in the queue, or using a custom comparator, should one be provided.
If we add to your current script to remove the five elements added, we will see that the items returned will be ordered from least to greatest:
public static void main(String args[]) {
addNum(-1);
addNum(-2);
addNum(-3);
addNum(-4);
addNum(-5);
// now remove all elements
while (!q.isEmpty()) {
System.out.println(q.remove());
}
}
This prints:
-5
-4
-3
-2
-1
If you need a collection which maintains sorting order, then consider using something like TreeSet. Or, you could use a regular ArrayList, and then call Collections.sort() if you want to impose a certain order.
PriorityQueue's implementation is a priority heap implementation & not sorted list.
The Iterator provided in method iterator() is not guaranteed to traverse the elements of the priority queue in any specific order. If you need ordered traversal, use something like:
Arrays.sort(q.toArray());
for (Integer data :q) {
System.out.println(data);
}
As other answers implied, you should use queue.poll() if you want to retrieve the elements in the right order, as in:
List<E> entities = new ArrayList<>();
while(!queue.isEmpty()){
entities.add(queue.poll());
}
The order of entities in the entities list will be as expected.
Rationale: Java PriorityQueue only ensures the order of enqueuing of the entities, not the order of iteration in an underlying collection.
The entities are mapped onto an underlying collection "unsorted", meaning if you try to access the entities using a stream:
queue.stream().collect(Collectors.toList());
or an iterator:
Iterator<E> i = queue.iterator();
...
E e = i.next()
or any other method, such as queue.forEach(), or in fact observe your queue in a IDE debugger, there is no guarantee as to the order of the entries in the collections obtained using any of these methods.
This the most Common Question, Many Collection Frame Work like ArrayList, LinkedList, and furthermore but In PriorityQueue, when you are printing the elements it will be in the Sorted Order and that order is followed MIN_HEAP property or
Basically, we can say that the Priority Queue is implemented on Min Heap Property.
So First Understand the MinHeap then implement the code.
I have implemented a graph.
I want to sort a given subset of vertices with respect to their degrees.
Therefore, I've written a custom comparator named DegreeComparator.
private class DegreeComparator implements Comparator<Integer>
{
#Override
public int compare(Integer arg0, Integer arg1)
{
if(adj[arg1].size() == adj[arg0].size()) return arg1 - arg0;
else return adj[arg1].size() - adj[arg0].size());
}
}
So, which one of the below is more efficient?
Using TreeSet
public Collection<Integer> sort(Collection<Integer> unsorted)
{
Set<Integer> sorted = new TreeSet<Integer>(new DegreeComparator());
sorted.addAll(unsorted);
return sorted;
}
Using ArrayList
Collections.sort(unsorted, new DegreeComparator());
Notice that the second approach is not a function, but a one-line code.
Intuitively, I'd rather choose the second one. But I'm not sure if it is more efficient.
Java API contains numerous Collection and Map implementations so it might be confusing to figure out which one to use. Here is a quick flowchart that might help with choosing from the most common implementations
A TreeSet is a Set. It removes duplicates (elements with the same degree). So both aren't equivalent.
Anyway, if what you want naturally is a sorted list, then sort the list. This will work whether the collection has duplicates or not, and even if it has the same complexity (O(n*log(n)) as populating a TreeSet, it is probably faster (because it just has to move elements in an array, instead of having to create lots of tree nodes).
If you only sort once, then the ArrayList is an obvious winner. The TreeSet is better if you add or remove items often as sorting a list again and again would be slow.
Note also that all tree structures need more memory and memory access indirection which makes them slower.
If case of medium sized lists, which change rather frequently by a single element, the fastest solution might be using ArrayList and inserting into the proper position (obviously assuming the arrays get sorted initially).
You'd need to determine the insert position via Arrays.binarySearch and insert or remove. Actually, I would't do it, unless the performance were really critical and a benchmark would show it helps. It gets slow when the list get really big and the gain is limited as Java uses TimSort, which is optimized for such a case.
As pointed in a comment, assuring that the Comparator returns different values is sometimes non-trivial. Fortunately, there's Guava's Ordering#arbitrary, which solves the problem if you don't need to be compatible with equals. In case you do, a similar method can be written (I'm sure I could find it somewhere if requested).
Hello Im a bit lost n the priority queues and comparator.
I dont really see how to make a comparator in java
So what I have is giving me a error and what I have read is no help to me
http://www.tutorialspoint.com/java/java_using_comparator.htm
This post game me some ideas but Im still stuck on how to do it
How do I use a PriorityQueue?
What i have is a class that creates an object with a priority, arrival time, and finish time.
I also have a number of priority queues to place them into. When i start I place them into the arrival queue to sort them and then see which one came in first and place that into the queue one. But when I try to add a second one to the arrival queue it fails and throws an exception.
What I want to do first is to add all the processes to the arrival queue and then sort them so the one with the smallest arrival time will be the first one out of the arrival queue and into the queue one.
Thanks for any help with this
//the comparator
Comparator<Integer> comparator = new Comparator();
//priority queues
//only needs 10 elements to hold
PriorityQueue one = new PriorityQueue(10, comparator);
PriorityQueue two = new PriorityQueue(10, comparator);
PriorityQueue three = new PriorityQueue(10, comparator);
PriorityQueue four = new PriorityQueue(10, comparator);
PriorityQueue arrival = new PriorityQueue(10, comparator);
//put all processes in arrival queue
arrival.add(p1);
arrival.add(p2);
arrival.add(p3);
arrival.add(p4);
arrival.add(p5);
arrival.add(p6);
arrival.add(p7);
arrival.add(p8);
arrival.add(p9);
arrival.add(p10);
Let's look at how you're defining Comparator, because at the moment I don't think what you've written would even compile.
Comparator is an interface, meaning that you need to define a class that implements it. That is, you need to define a class that has concrete implementations of the methods described by the interface. Here, there's only one method you need to worry about - compare. (The interface also defines equals, but that's an odd choice since it's equal to the one on Object and so every class will implement this by default...)
The compare method takes two objects of the target type, and decides which one of them comes "before" the other. It returns:
a negative integer, zero, or a positive integer as the
first argument is less than, equal to, or greater than the
second.
So - you want to compare objects of whatever the class of your p1, p2 instances are (I'll call it MyClass). That means that you have to define a class:
class MyComparator implements Comparator<MyClass> {
public int compare(MyClass a, MyClass b) {
// TODO
}
}
We know that the compare method should return a value depending on which of the MyClass arguments comes before the other one. You've said in your question that the one that comes first, is the one that has the smallest (i.e. earliest?) arrival time.
This is actually very easy, because that's the so-called natural ordering on java.util.Date objects - so you can just compare their arrival times against each other directly, as the result of that comparison is the same as the overall comparison.
Therefore the implementation of compare can simply be (assuming a sensibly-named accessor method):
public int compare(MyClass a, MyClass b) {
return a.getStartTime().compareTo(b.getStartTime());
}
And there you go! You've just defined your own comparator, that will sort MyClass objects by start time ascending. You can use it in the priority queues similarly to what you have already:
Comparator<MyClass> comparator = new MyComparator();
PriorityQueue<MyClass> arrival = new PriorityQueue<MyClass>(10, comparator);
Is there a method in JDK or apache commons to "pop" a list of elements from a java.util.List? I mean, remove the list of elements and return it, like this method:
public Collection pop(Collection elementsToPop, Collection elements) {
Collection popped = new ArrayList();
for (Object object : elementsToPop) {
if (elements.contains(object)) {
elements.remove(object);
popped.add(object);
}
}
return popped;
}
If you're looking for a stack-like structure I suggest accepting a Deque (LinkedList is the most common implementation) instead of a Collection.
If you don't actually need to treat it as a stack, just get an iterator from the Collection and use the remove() method:
for (Iterator<SomeType> it = elements.iterator(); it.hasNext(); ) {
SomeType e = it.next();
it.remove();
popped.add(e);
}
Do note that remove is an optional operation, and some implementations may throw an UnsupportedOperationException (for example, the iterator returned by a Collection from Collections.unmodifiable...() will).
Edit: After looking more closely at your question, I think you just need this:
elements.removeAll(elementsToRemove);
If your main point is you need to know exactly which elements were actually popped, I think you're stuck with your original code.
There is no such method in the standard JDK-provided methods. Apache Commons provides the ListUtils.subtract() method.
Edit: As other answerers have noted, your use of the term pop is nonstandard. Usually,
The pop operation removes an item from the top of [a stack]
Wikipedia has a nice description of stacks.
I guess no, because you definition of 'pop' operation is highly non-standard. Usually it takes no arguments (except collection itself) and returns and removes the top-most one.
But once you noted apache commons, this would achieve the same effect as your code.
Collection result = CollectionUtils.intersection(a, b);
a.removeAll(b);
edit
http://commons.apache.org/collections/api-release/index.html
Linked List provides the functionality as you require, provides a push and pop method.
Refer to the documentation as provided:
There isn't a method exactly like what you are asking for, but it looks like you are already pretty close with your code.
Some suggestions:
Consider using removeAll(object) instead of remove(object) if elements is an arbitrary collection since you may need to remove duplicates e.g. if elements is a list.
contains() is slow for some collection types (e.g. lists) since it needs to traverse the entire data structure. Given that this is in your inner loop you are at risk of O(n^2) performance issues. If you can make the algorithm work with a HashSet or HashMap then contains() will by O(1) and your algorithm will be much more efficient.