Javaのプライオリティキュー
私たちは、キューはFIFO(先入れ先出し)方式に従うことであることを知っているが、時にはキュー内で処理する必要がある優先順位に基づきます。例えば、我々は日々の取引セッションの株式レポート生成アプリケーションを持っているとしましょう、そして大量のデータを処理する必要が処理時間がかかります。クライアントがアプリケーションに要求を送信すると、実際には、彼がキューに入りました。私たちは、普通のユーザーを再処理の優先順位の顧客に対処する必要があります。この場合、Javaの優先度つきキュー(プライオリティキュー)が参考になります。
優先度つきキュークラスは、Java1.5で、Java Collections Frameworkの一部として導入します。優先度つきキューは、優先度ヒープアンバウンド形式のキューに基づいており、この優先度キューまたは要素が自然順序付けキューを提供するコンパレータ(コンパレータ)によってインスタンス化された注文デフォルトがあります。
プライオリティキューはNULLを許可しませんが、オブジェクトは、そのようなユーザ定義のクラスとして、(非比較)非同等でサポートしていません。これは、被験者へのJava同等のプライオリティキューとソートコンパレータインタフェースの使用を必要とし、処理は、並べ替えに優先順位要素に応じて、あろうことを特徴とします。
プライオリティキューが自然順序付けまたはソート比較に基づいて少なくとも素子ヘッドです。同じ種類を持っている複数のオブジェクトがある場合、それは、ランダムに任意に選択することができます。私たちはキューを取得すると、キューの先頭には、オブジェクトを返します。
プライオリティキューのサイズは制限されないが、初期サイズを作成する際に指定することができます。キューサイズが自動的に増加されたとき、私たちはプライオリティキューに要素を追加する場合。
優先度つきキューではないスレッドセーフで、JavaはPriorityBlockingQueue(BlockingQueueのインターフェイスを実装する)は、Javaマルチスレッド環境を提供します。
私たちは、それは、ソートのいずれかのタイプを提供していない、ユーザークラスの顧客を持っています。我々はプライオリティキューを確立するためにそれを使用すると、オブジェクトはのためのコンパレータを提供する必要があります。
Customer.java
パッケージcom.journaldev.collections。
パブリッククラスカスタマー{
プライベートint型のID。 プライベート文字列名;
公共の顧客(INT I、文字列N){ this.id = I; this.name = N。 }
公共INTのgetId(){ IDを返します。 }
パブリック文字列のgetName(){ 名前を返します。 }
} |
私たちは、Javaの乱数生成器のランダムユーザオブジェクトを使用しています。自然の秩序のために、我々はあまりにもJavaオブジェクトのパッケージであるIntegerオブジェクトを使用します。
ここでは、究極のテストコードがあり、優先度つきキューを使用する方法を示しています。
PriorityQueueExample.java
パッケージcom.journaldev.collections。
java.util.Comparatorのインポート; 輸入java.util.PriorityQueue。 輸入java.util.Queue。 java.util.Randomのインポート。
パブリッククラスPriorityQueueExample {
パブリック静的無効メイン(文字列[] args){
自然順序付け例//プライオリティキュー キュー<整数> integerPriorityQueue =新しい優先度つきキュー<>(7)。 ランダムランド=新しいランダム(); {(; iが7 <I ++はiが0 = INT)のために integerPriorityQueue.add(新しい整数(rand.nextInt(100))); } {(; iが7 <I ++はiが0 = INT)のために = integerPriorityQueue.pollの整数(); System.out.println("Processing Integer:"+in); }
//优先队列使用示例 Queue<Customer> customerPriorityQueue = new PriorityQueue<>(7, idComparator); addDataToQueue(customerPriorityQueue);
pollDataFromQueue(customerPriorityQueue);
}
//匿名Comparator实现 public static Comparator<Customer> idComparator = new Comparator<Customer>(){
@Override public int compare(Customer c1, Customer c2) { return (int) (c1.getId() - c2.getId()); } };
//用于往队列增加数据的通用方法 private static void addDataToQueue(Queue<Customer> customerPriorityQueue) { Random rand = new Random(); for(int i=0; i<7; i++){ int id = rand.nextInt(100); customerPriorityQueue.add(new Customer(id, "Pankaj "+id)); } }
//用于从队列取数据的通用方法 private static void pollDataFromQueue(Queue<Customer> customerPriorityQueue) { while(true){ Customer cust = customerPriorityQueue.poll(); if(cust == null) break; System.out.println("Processing Customer with ID="+cust.getId()); } }
} |
注意我用实现了Comparator接口的Java匿名类,并且实现了基于id的比较器。
当我运行以上测试程序时,我得到以下输出:
Processing Integer:9 Processing Integer:16 Processing Integer:18 Processing Integer:25 Processing Integer:33 Processing Integer:75 Processing Integer:77 Processing Customer with ID=6 Processing Customer with ID=20 Processing Customer with ID=24 Processing Customer with ID=28 Processing Customer with ID=29 Processing Customer with ID=82 Processing Customer with ID=96 |
从输出结果可以清楚的看到,最小的元素在队列的头部因而最先被取出。如果不实现Comparator,在建立customerPriorityQueue时会抛出ClassCastException。
Exception in thread "main" java.lang.ClassCastException: com.journaldev.collections.Customer cannot be cast to java.lang.Comparable at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:633) at java.util.PriorityQueue.siftUp(PriorityQueue.java:629) at java.util.PriorityQueue.offer(PriorityQueue.java:329) at java.util.PriorityQueue.add(PriorityQueue.java:306) at com.journaldev.collections.PriorityQueueExample.addDataToQueue(PriorityQueueExample.java:45) at com.journaldev.collections.PriorityQueueExample.main(PriorityQueueExample.java:25) |