我正在尝试在Java中创建优先级阻塞队列,以维护具有相同优先级的元素的FIFO顺序。 Oracle文档对此提供了一些帮助,但是我仍然很纠结。
我应该注意,以下主题对我而言都是非常新的:泛型,作为类型的接口(interface)和静态嵌套类。所有这些都在下面的类定义中起作用。泛型尤其令人困惑,我敢肯定,我在这里完全搞砸了它们。
我已包含一些注释,以标识我当前遇到的编译器错误。
几个特定的问题:
这是我编写的类(class):
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
public class FIFOPBQEvent {
/**
* First we define a static nested class which, when instantiated,
* encapsulates the "guts" of the event - a FIFOPBQEvent - along with
* a sequence number that assures FIFO behavior of events of like priority.
*
* The following is lifted ALMOST verbatim (I added "static" and some
* comments) from Oracle documentation on adding FIFO-ness to a Priority
* Blocking Queue:
* http://download.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html
* As the Oracle doc points out:
*
* "A static nested class interacts with the instance members of its outer
* class (and other classes) just like any other top-level class. In
* effect, a static nested class is behaviorally a top-level class that
* has been nested in another top-level class for packaging convenience."
*
*/
static class FIFOEntry<E extends Comparable<? super E>> implements
Comparable<FIFOEntry<E>> {
final static AtomicLong seq = new AtomicLong();
final long seqNum; // instance
final E entry;
public FIFOEntry(E entry) {
seqNum = seq.getAndIncrement();
this.entry = entry;
}
public E getEntry() {
return entry;
}
/** Here is implementation of Comparable */
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;
}
}
/**
* Now we declare a single (static) PBQ of FIFO entries into which
* PBQFIFOEvents will be added and removed.
*/
/** FLAGGED AS ERROR BY COMPILER */
// Bound mismatch: The type FIFOPBQEvent is not a valid substitute for the
// bounded parameter <E extends Comparable<? super E>> of the type
// FIFOPBQEvent.FIFOEntry<E>
private static PriorityBlockingQueue<FIFOEntry<FIFOPBQEvent>> theQueue =
PriorityBlockingQueue<FIFOEntry<FIFOPBQEvent>>();
/**
* And here are the "guts" of our event: the i.d. and state of the GUI widget
*/
private ConsoleObject obj = ConsoleObject.UNDEFINED_OBJ; // widget that was affected
private ObjectState state = ObjectState.UNDEFINED_STATE; // the widget's new state
/**
* Constructor specifying the class variables
*/
public FIFOPBQEvent(ConsoleObject theObj, ObjectState theState) {
obj = theObj;
state = theState;
}
/**
* Event queuing ("sending") and dequeuing ("receiving")
*/
public void sendEvent() {
/** FLAGGED AS ERROR BY COMPILER */
// The method put(FIFOPBQEvent.FIFOEntry<FIFOPBQEvent>) in the type
// PriorityBlockingQueue<FIFOPBQEvent.FIFOEntry<FIFOPBQEvent>> is not
// applicable for the arguments (FIFOPBQEvent)
theQueue.put(this);
}
public static FIFOPBQEvent receiveEvent() {
/** FLAGGED AS ERROR BY COMPILER */
// Type mismatch: cannot convert from FIFOPBQEvent.FIFOEntry<FIFOPBQEvent>
// to FIFOPBQEvent
FIFOPBQEvent event = theQueue.take();
return event;
}
/**
* ConsoleEvent accessors
*/
public ConsoleObject getObj() {
return this.obj;
}
public ObjectState getState() {
return this.state;
}
/**
* And for the first time, enums instead of public static final ints.
*/
public enum ConsoleObject {
UNDEFINED_OBJ,
RESERVED,
/** Console keys */
RESET,
DISPLAY_MAR,
SAVE,
INSERT,
RELEASE,
START,
SIE,
SCE,
/** Console toggle switches */
POWER,
PARITY_CHECK,
IO_CHECK,
OVERFLOW_CHECK,
SENSE_SWITCH_1,
SENSE_SWITCH_2,
SENSE_SWITCH_3,
SENSE_SWITCH_4
}
public enum ObjectState {
UNDEFINED_STATE,
/** Toggle switches */
OFF,
ON,
/** Console keys */
PRESSED,
}
}
最佳答案
第一个错误是更重要的错误。发生这种情况是因为FIFOPBQEvent
类未实现Comparable
,必须将其视为FIFOEntry
嵌套类的通用类型。这是因为您限制E
并说它为extends Comparable<...>
。基本上,您的FIFOPBQEvent
类必须具有可比性,才能为队列提供优先级(大概基于事件类型)。
要修复该错误,您需要:
public class FIFOPBQEvent implements Comparable<FIFOPBQEvent> {
compareTo
类中添加FIFOPBQEvent
方法;就像是:public int compareTo (FIFOPBQEvent other) {
// TODO - compare this and other for priority
return 0;
}
然后,您需要将条目包装在
sendEvent
方法中:public void sendEvent () {
theQueue.put(new FIFOEntry<FIFOPBQEvent> (this));
}
最后一个较小的错误就是您没有展开
FIFOEntry
对象。要解决此问题,请将receiveEvent
更改为:public static FIFOPBQEvent receiveEvent () {
FIFOPBQEvent event = theQueue.take ().getEntry ();
return event;
}