Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a PriorityQueue implementation with fixed capacity and custom comparator?

Related questions:

  • Java PriorityQueue with fixed size
  • How do I use a PriorityQueue?
  • get indexes of n smallest elements in an array
  • Scala: Is there a way to use PriorityQueue like I would in Java?

I have a very large data set (more than 5 millions items) and I need to get N largest items from it. The most natural way to do it is to use heap/priority queue storing only top N items. There are several good implementations of priority queue for JVM (Scala/Java), namely:

  • scala.collection.mutable.PriorityQueue
  • java.util.PriorityQueue
  • lucene.util.PriorityQueue

First 2 are nice, but they store all the items, which in my case gives critical memory overhead. Third (Lucene implementation) doesn't have such a drawback, but as I can see from documentation it also doesn't support custom comparator, which makes it useless for me.

So, my question is: Is there a PriorityQueue implementation with fixed capacity and custom comparator?

UPD. Finally I've created my own implementation, based on Peter's answer:

public class FixedSizePriorityQueue<E> extends TreeSet<E> {      private int elementsLeft;      public FixedSizePriorityQueue(int maxSize) {         super(new NaturalComparator());         this.elementsLeft = maxSize;     }      public FixedSizePriorityQueue(int maxSize, Comparator<E> comparator) {         super(comparator);         this.elementsLeft = maxSize;     }       /**      * @return true if element was added, false otherwise      * */     @Override     public boolean add(E e) {         if (elementsLeft == 0 && size() == 0) {             // max size was initiated to zero => just return false             return false;         } else if (elementsLeft > 0) {             // queue isn't full => add element and decrement elementsLeft             boolean added = super.add(e);             if (added) {                 elementsLeft--;             }             return added;         } else {             // there is already 1 or more elements => compare to the least             int compared = super.comparator().compare(e, this.first());             if (compared == 1) {                 // new element is larger than the least in queue => pull the least and add new one to queue                 pollFirst();                 super.add(e);                 return true;             } else {                 // new element is less than the least in queue => return false                 return false;             }         }     } } 

(where NaturalComparator is taken from this question)

like image 274
ffriend Avatar asked Oct 24 '11 15:10

ffriend


People also ask

How does PriorityQueue use Comparator?

PriorityQueue. comparator() method shares an important function of setting and returning the comparator that can be used to order the elements in a PriorityQueue. The method returns a null value if the queue follows the natural ordering pattern of the elements. Parameters: The method does not take any parameters.

How is PriorityQueue implemented in Java?

Class PriorityQueue<E> An unbounded priority queue based on a priority heap. 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. A priority queue does not permit null elements.

How do you implement PriorityQueue?

Implementation of Priority Queue Priority queue can be implemented using an array, a linked list, a heap data structure, or a binary search tree. Among these data structures, heap data structure provides an efficient implementation of priority queues.

What is PriorityQueue explain with an example?

The priority queue supports only comparable elements, which means that the elements are either arranged in an ascending or descending order. For example, suppose we have some values like 1, 3, 4, 8, 14, 22 inserted in a priority queue with an ordering imposed on the values is from least to the greatest.


2 Answers

How can you say Lucene's doesn't support a custom comparator?

Its abstract and you must implement the abstract method lessThan(T a, T b)

like image 99
Robert Muir Avatar answered Sep 28 '22 18:09

Robert Muir


You could use a SortedSet e.g. TreeSet with a custom comparator and remove the smallest when the size reachs N.

like image 24
Peter Lawrey Avatar answered Sep 28 '22 17:09

Peter Lawrey