2016-11-04 7 views
-1

私は、キーと値を持つPairという名前のあらかじめ定義されたクラスを持っています。私は、各ペアの自然な順序に基づいてPriorityQueueにそれらを格納します。ペアの1つの値を変更してからデキューすると、私が期待していたことは起こりませんでした。テストコードは以下の通りです。助けてください。私は混乱しているように感じる!投票を行うとPriorityQueueはどのように機能するのですか?

import java.util.*; 
public class Test { 
    static class Pair { 
     int key; 
     int value; 
     Pair (int key, int value) { 
     this.key = key; 
     this.value = value; 
     } 
    } 
    public static void main(String[] args) { 
     PriorityQueue<Pair> pq = new PriorityQueue<Pair>(3, new Comparator<Pair>() { 
     @Override 
     public int compare(Pair p1, Pair p2) { 
      return p1.value - p2.value; 
     } 
    }); 
    Pair p1 = new Pair(1, 31); 
    Pair p2 = new Pair(2, 32); 
    Pair p3 = new Pair(3, 33); 
    pq.offer(p1); 
    pq.offer(p2); 
    pq.offer(p3); 
    p2.value = 31; 
    p1.value = 32; 
    Pair p0 = pq.poll(); // It shows the reference p0 is p1 not expected p2. 
         // And what remain in pq are p2 with 31 and p3 with 33 
    } 
} 

ポーリング時にPriorityQueueがアイテムをソートすることがわかりました。私の例ではPriorityQueueが機能しなかったようです。

+0

なぜp2が必要ですか? –

+1

"ポーリング時にPriorityQueueがアイテムをソートすることはわかっています" < - 本当ですか? JavaDocは、pollメソッドのようなものは何も言わず、ポーリングメソッドは単純に、現在のオブジェクトをインデックス0に戻してから、そのキューをソートします。 –

+0

@SotiriosDelimanolis私は、p2の 'value'(比較関数に使用される)が3つの' Pair'の中で最小であり、 'PriorityQueue'が' Pair'を最小値 'p2 'でポーリングすべきだと考えました。 –

答えて

4

ハッシュマップ/セット、TreeMap/Set、またはPriorityQueueのようなソートされたキューのようなデータ構造を持つ場合、要素の1つ(特にhashCode/equals/compareToに使用されるフィールドを、メソッドが使用されている場合)、データ構造は自分自身を再配置することを知らず、代わりにデータ構造を破壊して期待どおりに機能しません。

要するに、データ構造内のオブジェクトのキーフィールドを変更して、それが信頼できる方法で動作することは期待できません。

+1

ありがとうございました!分かりました。特定のオブジェクトの優先度を更新する場合は、PriorityQueueから削除し、キーを変更してから再度挿入するか、自分でヒープを作成する必要があります。 –

+0

@WalterWangはい、多くのデータ構造(配列やリストを除く)で何をする必要があるのか​​、 –

関連する問題