我知道什么是优先级队列,我知道如何添加字符串/整数。但现在我想为它添加功能。 (如果这有道理??)。我还没准备好改变任何函数的返回类型。
我想知道我该怎么做呢?我创建了一个原始类型优先级队列
PriorityQueue prq = new PriorityQueue ();
prg.offer(login());
现在,我不是编码天才,我也在学习。所以我想看看它是否可行。如果不可能有替代解决方案吗?
我的pop()函数将运行弹出的函数。我的大部分功能都无效。
我得到的一个想法:我是否应该插入字符串并根据我弹出的字符串执行switch语句()???
答案 0 :(得分:0)
您不能将该函数用作优先级队列的参数(在java中),但只要该函数的返回类型与所需参数匹配,您就可以使用该函数的返回值。
offer()中的参数类型由泛型指定。这是代码示例。
public static int login(){
return 0;
}
public static void main (String[] args){
PriorityQueue<Integer> prq = new PriorityQueue<Integer>();
prg.offer(login());
}
然后,您可以将整数更改为函数login()的返回类型。
答案 1 :(得分:0)
一般来说,可以做这样的事情,但我建议你考虑一下。实施有点笨拙。
首先,您正在使用优先级队列。这意味着您希望按优先级顺序接收添加到其中的内容。优先级队列是有序集合。为此,您放入其中的项目必须为Comparable
。这就是String或Integer的优先级队列工作的原因。它们都是Comparable
- 如果你在队列中有两个字符串,那么很容易分辨出哪个是第一个,因为字符串有一个自然顺序。尽管如此,必须说在现实生活中,你通常不会分配字符串优先级。优先级队列应该表示哪些事情更迫切需要处理,哪些事情更少。所以通常优先级更有可能被实现为某种数字或枚举。
因此,除了将一个函数放入队列之外,还需要在将其放入队列时为其分配优先级,这将告诉谁从队列中读取哪个函数更难以执行。他只是按优先顺序得到它们。
因此我们需要定义某种对象,它将封装函数和优先级:
public final class PrioritizedPerformer implements Comparable<PrioritizedPerformer> {
/**
* Actor interface. Represents a way to run a function.
*/
public interface Actor {
void perform();
}
/**
* Available priorities
*/
public enum Priority { URGENT, HIGH, MEDIUM, LOW };
private Priority priority;
private Actor actor;
/**
* Constructor that allows creating PrioritizedPerformer objects with a given priority and actor.
*
* @param priority Priority of this object when placed in a priority queue.
* @param actor Actor representing a function to be performed.
*/
public PrioritizedPerformer(Priority priority, Actor actor) {
// Don't allow null priorities, this will cause problems in priority queues.
if ( priority == null ) {
throw new IllegalArgumentException("Must provide valid priority");
}
this.priority = priority;
// Don't allow null actors. The action has to be available.
if ( actor == null ) {
throw new IllegalArgumentException("Must provide valid actor");
}
this.actor = actor;
}
/* Allows prioritizing one PrioritizedPerformer over another.
*
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
@Override
public int compareTo(PrioritizedPerformer o) {
return priority.compareTo(o.priority);
}
/**
* Perform whatever action the actor represents.
*/
public void perform() {
actor.perform();
}
}
现在我们有了这个,我们可以将这种类型的对象放入优先级队列:
PriorityQueue<PrioritizedPerformer> queue = new PriorityQueue<PrioritizedPerformer>();
queue.offer(new PrioritizedPerformer(
PrioritizedPerformer.Priority.HIGH,
new PrioritizedPerformer.Actor() {
public void perform() {
login();
}
}));
queue.offer(new PrioritizedPerformer(
PrioritizedPerformer.Priority.LOW,
new PrioritizedPerformer.Actor() {
public void perform() {
quit();
}
}));
queue.offer(new PrioritizedPerformer(
PrioritizedPerformer.Priority.URGENT,
new PrioritizedPerformer.Actor() {
public void perform() {
returnThree();
}
}));
我们在这里做的是使用给定的PrioritizedPerformer
构建每个Priority
对象和执行我们希望它执行的函数的匿名Actor
。
现在我们可以运行:
queue.remove().perform();
这将从队列中删除最高优先级的对象,并运行其perform()
方法,该方法调用其内部Actor
的{{1}}方法。在这种情况下,它将采用优先级为perform()
的那个,恰好运行函数URGENT
。
所以这会做你要求的。然而我建议反对它。它只能执行没有参数的函数(或者只调用具有预定参数的特定函数)。你无法传递类似returnThree()
的内容,因为当你需要执行它时,你无法将数字传递给该函数。
这导致使用全局范围字段将数据传递给各种函数而不是参数。这反过来会导致可读性问题,缺少封装,这意味着您的参数可能会被您不打算更改它们的方法所改变。这是各种各样的坏事。此外,在此特定设置中,如果您不知道接下来要运行哪个功能,您将如何知道在全局范围内设置哪些参数?
答案 2 :(得分:-1)
您目前正在做的是将该函数的返回值放入队列中。因此,函数执行,然后将它生成的值放入队列。相反,您可以拥有Runnable
的队列,然后在其上调用run()
方法:
PriorityQueue<Runnable> queue = new PriorityQueue<Runnable>();
queue.offer( new Runnable() { public void run() { login(); } );
queue.remove().run();
或者,如果使用Java 8:
PriorityQueue<Runnable> queue = new PriorityQueue<>();
queue.offer(() -> login(););