我正在使用优先级队列(java.util.PriorityQueue<T>
),其中具有相同优先级的项目需要以先进先出的方式处理。
我通过向添加到队列中的项添加时间戳成员来管理这一点,该队列为每个添加的项增加。 (请参阅PriorityQueue has objects with the same priority和http://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;
}
}
我现在要做的是能够确定某个项目是否在队列中和/或能够从中删除项目。我不能直接使用contains
或remove
函数,因为队列包含FIFOEntry对象,而不是E
对象。
队列的contains(Object o)
和remove(Object o)
函数取决于参数'o.equals(e)
函数。我可以通过将equals()
函数添加到仅使用FIFOEntry
成员进行比较的entry
类来删除项目。
我需要一个比这更好的方法,因为这个新的equals
函数打破了“与equals一致”的规则。
创建一个具有条目成员(相同类型E)并将equals()
函数移动到另一个类的新的单独类会不会更好?那么使用比较器呢?
P.S。更多上下文:这将在Android中使用。
答案 0 :(得分:0)
如果您为hashcode
类(条目)正确覆盖compareTo
,equals
和E
,那么一切都会正常。
上面的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
(以及其他等于的地方)被叫),检查上面的代码片段(编辑它)。