Making a Java PriorityQueue into a stable priority queue

前端 未结 3 1179
鱼传尺愫
鱼传尺愫 2020-12-11 06:58

I\'m trying to implement a stable (first in first out) priority queue in Java. Supposing that the key is a name and the value is an age, I know I can make an unstable prior

相关标签:
3条回答
  • 2020-12-11 07:50

    You need something like this:

    import java.util.AbstractMap;
    import java.util.Comparator;
    import java.util.PriorityQueue;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class PriorityTest {
      @SuppressWarnings("serial")
      private static class Entry extends AbstractMap.SimpleEntry<String, Integer> {
        private final static AtomicInteger seq = new AtomicInteger(0);
        final int order;
        public Entry(final String _key, final Integer _value) {
          super(_key, _value);
          order = seq.incrementAndGet();
        }
      }
    
      private static class OrderedComparator implements Comparator<Entry> {
        @Override
        public int compare(final Entry _e1, final Entry _e2) {
          int r = _e1.getValue().compareTo(_e2.getValue());
          if (r == 0)
            return Integer.compare(_e1.order, _e2.order);
          return r;
        }
      }
    
      public static void main(String[] args) {
        final PriorityQueue<Entry> pq = new PriorityQueue<Entry>(10, new OrderedComparator());
        pq.add(new Entry("Jane", 22));
        pq.add(new Entry("John", 15));
        pq.add(new Entry("Bill", 45));
        pq.add(new Entry("Bob", 22));
        while(!pq.isEmpty()) {
          System.out.println(pq.remove());
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-11 07:53

    Very simple implementation based on multiple lists and TreeMap I've done today to solve some task:

    import javax.annotation.Nonnull;
    import java.util.*;
    import java.util.Map.Entry;
    import java.util.function.Function;
    
    public class PriorityFifo<E> {
    
         protected TreeMap<Integer, LinkedList<E>> storage = new TreeMap<>();
    
         public void push(E element, int priority) {
            storage.computeIfAbsent(priority, it -> new LinkedList<>()).addLast(element);
         }
    
         public Optional<E> poll() {
            return doWithNextElement(LinkedList::pollFirst);
         }
    
         public Optional<E> peek() {
            return doWithNextElement(LinkedList::getFirst);
         }
    
         protected Optional<E> doWithNextElement(@Nonnull Function<LinkedList<E>, E> f) {
             Entry<Integer, LinkedList<E>> entry = storage.firstEntry();
             if (entry==null)
                 return Optional.empty();
             LinkedList<E> list = entry.getValue();
             E element = f.apply(list);
             if (list.isEmpty())
                 storage.remove(entry.getKey());
             return Optional.of(Objects.requireNonNull(element));
    
         }
    
    }
    

    No comparator used for elements, but used internally by TreeMap for queues. My case is that I have only a few of priorities, but a lot of elements, so it should go faster than something using element comparison.

    0 讨论(0)
  • 2020-12-11 07:57

    Keap-based PriorityQueue is naturally stable. It's written in Kotlin, so it can replace java.util.PriorityQueue in Java code.

    0 讨论(0)
提交回复
热议问题