Java中的优先级队列

时间:2010-10-25 02:36:51

标签: java priority-queue

你能拥有2个参数吗?例如,我想将一个字符串和一个相应的整数添加到优先级键。然后我将按整数排序。我知道如何添加字符串或整数,但我不知道如何添加它们。有人可以指出我正确的方向,让我知道我是否正确地走这条路?

4 个答案:

答案 0 :(得分:12)

有两种方法可以做到这一点。无论哪种方式,您都希望创建一个自定义对象,该对象同时包含String(您想要的值)和整数(优先级)。

第一个解决方案是让这个数据对象实现Comparable

class Data implements Comparable<Data> {
  private final String message;
  private final int priority;

  public Data(String message, int priority) {
    this.message = message;
    this.priority = priority;
  }

  @Override
  int compareTo(Data other) {
    return Integer.valueOf(priority).compareTo(other.priority);
  }

  // also implement equals() and hashCode()
}

然后当你做

PriorityQueue<Data> queue = new PriorityQueue<Data>();

队列将按照compareTo方法定义的顺序对项目进行排序。

此解决方案的问题在于,如果您希望排序仅在整数上,那么equals方法和compareTo方法将不一致或您的equals方法不正确。

更好的解决方案是使用PriorityQueueComparator构造函数。在这种情况下,Data不必实施Comparable;你只需要一个Comparator来定义你的订单:

public final class OrderDataByPriority implements Comparator<Data> {
  public static final OrderDataByPriority INSTANCE = new OrderDataByPriority();

  private OrderDataByPriority() {}

  @Override
  public int compare(Data data1, Data data2) {
    return Integer.valueOf(data1.priority).compareTo(data2.priority);
  }

  @Override
  public boolean equals(Object other) {
    return other == OrderDataByInteger.INSTANCE;
  }

  private Object readResolve() {
    return INSTANCE;
  }
}

请注意,由于此比较器没有数据,因此我将其设为单例。

然后您可以创建此队列行:

PriorityQueue<Data> queue = new PriorityQueue<Data>(
    initialCapacity, OrderDataByPrority.INSTANCE);

答案 1 :(得分:4)

以下是执行此操作的一般方法:

public class PriorityQueue<T> {

    private java.util.PriorityQueue<IntPriorityComparableWrapper<T>> queue;

    public PriorityQueue() {
            queue = new java.util.PriorityQueue<IntPriorityComparableWrapper<T>>();
    }

    public void add( int priority, T object ) {
            queue.add( new IntPriorityComparableWrapper<T>(object, priority) );
    }

    public T get() {
            return (null != queue.peek())? queue.poll().getObject() : null;
    }


    /**
     * A "wrapper" to impose comparable properties on any object placed in the
     * queue.
     */
    private static class IntPriorityComparableWrapper<T>
    implements Comparable<IntPriorityComparableWrapper<T>> {

            private T object;
            private int priority;

            public IntPriorityComparableWrapper( T object, int priority ) {
                    this.object = object;
                    this.priority = priority;
            }

            public int compareTo( IntPriorityComparableWrapper<T> anotherObject ) {
                    return this.priority - anotherObject.priority;
            }

            public int getPriority() {
                    return priority;
            }

            public T getObject() {
                    return object;
            }
    }

}

答案 2 :(得分:3)

如何创建包含这两个字段(intString)的新类,然后实现Comparable(在int字段上进行比较)。不要忘记同时覆盖hashCode()equals()(有关覆盖这些方法的原因,请参阅Comparable类javadoc。)

这就是你追求的目标吗?

答案 3 :(得分:2)

如果要将多个元素用作键,可以创建一个封装两者的类,然后使用该类型作为键。同样对于价值观。您应该创建此自定义密钥类Comparable,覆盖equals(),并覆盖您创建的自定义密钥类的hashCode()