从PriorityQueue中删除带时间戳的项目

时间:2015-02-18 05:11:34

标签: java priority-queue

我正在使用优先级队列(java.util.PriorityQueue<T>),其中具有相同优先级的项目需要以先进先出的方式处理。

我通过向添加到队列中的项添加时间戳成员来管理这一点,该队列为每个添加的项增加。 (请参阅PriorityQueue has objects with the same priorityhttp://docs.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html

所以使用我所拥有的文档中的FIFOEntry类

 class FIFOEntry<E extends Comparable<? super E>>
     implements Comparable<FIFOEntry<E>> {
   final static AtomicLong seq = new AtomicLong();
   final long seqNum;
   final E entry;
   public FIFOEntry(E entry) {
     seqNum = seq.getAndIncrement();
     this.entry = entry;
   }
   public E getEntry() { return entry; }
   public int compareTo(FIFOEntry<E> other) {
     int res = entry.compareTo(other.entry);
     if (res == 0 && other.entry != this.entry)
       res = (seqNum < other.seqNum ? -1 : 1);
     return res;
   }
 }

我现在要做的是能够确定某个项目是否在队列中和/或能够从中删除项目。我不能直接使用containsremove函数,因为队列包含FIFOEntry对象,而不是E对象。

队列的contains(Object o)remove(Object o)函数取决于参数'o.equals(e)函数。我可以通过将equals()函数添加到仅使用FIFOEntry成员进行比较的entry类来删除项目。

我需要一个比这更好的方法,因为这个新的equals函数打破了“与equals一致”的规则。

创建一个具有条目成员(相同类型E)并将equals()函数移动到另一个类的新的单独类会不会更好?那么使用比较器呢?

P.S。更多上下文:这将在Android中使用。

1 个答案:

答案 0 :(得分:0)

如果您为hashcode类(条目)正确覆盖compareToequalsE,那么一切都会正常。

上面的FIFOEntry类是Composition的示例。

您可以覆盖equals方法,如下所示。

@Override public boolean equals(Object o){
   if(!(o instanceof FIFOEntry)){
      return false;
   }
   FIFOEntry cp= (FIFOEntry) o;
   return cp.entry.equals(entry) && cp.seqNum.equals(seqNum);
}

如果在FIFOEntry类中设置的Entry对象具有compareTo和相同的seq编号,则FiFOEntry 0将返回same entry object reference。基本上是相同的对象。

compareTo和equals一致性将取决于您在E类中如何实现它们。

import java.util.Iterator;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;

public class Test123 {
    public static void main(String[] args) {
        E x = new Test123.E(1);
        PrivateBlockingQueue queue = new Test123.PrivateBlockingQueue();
        FIFOEntry<E> e1 = new Test123.FIFOEntry<E>(x);
        FIFOEntry<E> e2 = new Test123.FIFOEntry<E>(new E(2));
        FIFOEntry<E> e3 = new Test123.FIFOEntry<E>(new E(1));

        queue.add(e1);
        queue.add(e2);
        queue.add(e3);

        System.out.println(queue.contains(x));
        while (true) {
            FIFOEntry<E> t = queue.poll();
            if (t == null) {
                break;
            }
            if (t.equals(e1)) {
                System.out.println("hi this is E1");
                System.out.println(t.compareTo(e1));
            }
            System.out.println(t.getEntry().getInt() + " " + t.seqNum);
        }

    }

    @SuppressWarnings("serial")
    static class PrivateBlockingQueue extends
            PriorityBlockingQueue<FIFOEntry<E>> {
        public boolean contains(E o) {
            Iterator<FIFOEntry<E>> itr = iterator();
            while (itr.hasNext()) {
                FIFOEntry<E> x = itr.next();
                if (x.entry.equals(o)) {
                    return true;
                }
            }
            return false;
        }
    }

    static class E implements Comparable<E> {
        final private Integer xyz;

        public E(int e) {
            this.xyz = e;
        }

        public Integer getInt() {
            return xyz;
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof E)) {
                return false;
            }
            E test = (E) obj;
            return test.getInt() == xyz;
        }

        @Override
        public int compareTo(E o) {
            if (xyz < o.getInt()) {
                return -1;
            }
            if (xyz > o.getInt()) {
                return 1;
            }
            return 0;
        }
    }

    static class FIFOEntry<E extends Comparable<? super E>> implements
            Comparable<FIFOEntry<E>> {
        final static AtomicLong seq = new AtomicLong();
        final long seqNum;
        final E entry;

        public FIFOEntry(E entry) {
            seqNum = seq.getAndIncrement();
            this.entry = entry;
        }

        public E getEntry() {
            return entry;
        }

        public int compareTo(FIFOEntry<E> other) {
            int res = entry.compareTo(other.entry);
            if (res == 0 && other.entry != this.entry)
                res = (seqNum < other.seqNum ? -1 : 1);
            return res;
        }

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof FIFOEntry)) {
                return false;
            }
            @SuppressWarnings("rawtypes")
            FIFOEntry cp = (FIFOEntry) o;
            return cp.entry.equals(entry) && cp.seqNum == seqNum;
        }
    }
}

修改

根据您的要求检查优先级中是否存在类E并且还要维护equals和compareTo一致性,您可以扩展和重载contains(以及其他等于的地方)被叫),检查上面的代码片段(编辑它)。