2014-11-04 72 views
0

我知道什麼是優先級隊列,我知道如何添加字符串/整數。但現在我想添加功能。 (如果這是合理的??)。我沒有準備好更改任何函數的返回類型。如何將函數添加到優先級隊列? (它甚至可能)

我想知道我該怎麼做呢?我做了一個原始類型的優先隊列

PriorityQueue prq = new PriorityQueue(); 
prg.offer(login()); 

現在,我不是編碼天才,我也在學習。所以我想看看它是否可能。如果不可能,是否有其他解決方案?

我的pop()函數只會運行彈出的函數。我的大部分功能都是無效的。

我有一個想法:我應該只是插入字符串,並根據哪個字符串做一個switch語句我彈出()?

+1

Java不是JavaScript,函數(Java中的「方法」)不是可以分配給變量(甚至是匿名變量)的東西,然後傳遞。編程模型相當不同,所以你可以花一個小時閱讀官方的[Java基礎知識](http://docs.oracle.com/javase/tutorial/java/index.html)。不需要那麼長時間,並且在理解Java可以,不可以,不想做和不可以做的事情方面給你一個很大的提升。 – 2014-11-04 17:52:16

+0

其實java可以做我問的問題,有人確實回答了我的需求(指向最佳答案)謝謝:) – Indigo 2014-11-04 18:00:26

+2

實際上,它不能,你得到的答案是關於創建一個新的Runnable實例,它被調用來運行與調用方法的方式不同。它可以做你想做的事,但你想做的是打破不少Java最佳實踐和約定=) – 2014-11-04 18:02:32

回答

-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();); 
+0

我喜歡你和你的想法!讓我試試吧! :D – Indigo 2014-11-04 17:51:48

+0

你是對的!這正是我想要的!愛的感謝謝謝! :D – Indigo 2014-11-04 17:59:47

+1

@Indigo你應該也可以使用lambdas而不是匿名類,但我不知道在java中如何做到這一點。如果有其他人,請編輯答案。 – clcto 2014-11-04 17:59:57

0

您不能將該函數用作優先級隊列的參數(在java中),但只要函數的返回類型與所需參數匹配,您就可以使用函數的返回值。

offer()中參數的類型由泛型指定。這裏是代碼示例。

public static int login(){ 

    return 0; 
} 

public static void main (String[] args){ 


    PriorityQueue<Integer> prq = new PriorityQueue<Integer>(); 
    prg.offer(login()); 
} 

然後,您可以更改整數到任何的返回類型的函數登錄()。

+0

正如我的問題所述,我不準備改變任何函數的返回類型。 – Indigo 2014-11-04 17:51:13

+0

您沒有指定函數的返回類型。如果它是無效的,答案是「不,你不能」,如果它是別的東西,那麼就把** Integer **改成你函數的返回類型。 – 2014-11-04 17:53:15

+0

我提到過我的大部分功能在我的問題中都是無效的,感謝您的建議,我會仔細研究一下。 – Indigo 2014-11-04 17:56:19

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()方法,它調用其內部的Actorperform()方法。在這種情況下,它將採用優先級爲URGENT的驅動程序,該驅動程序恰好運行功能returnThree()

所以這將做你所要求的。但我反對它。它只能執行沒有參數的函數(或者僅僅調用具有預定參數的特定函數)。你不能通過它像Math.sqrt,因爲當你需要執行它時,你無法將數字傳遞給該函數。

這會導致使用全局範圍字段將數據傳遞給各種函數而不是參數。這反過來導致可讀性問題,缺少封裝,這意味着您的參數可能會被您不打算改變它們的方法改變。這是各種各樣的不好。另外,在這個特定的設置中,如果您不知道下一步將運行哪個函數,您將如何知道要在全局範圍中設置哪些參數?