2013-08-21 89 views
7

Tôi vừa học về hàng đợi ưu tiên và nghĩ rằng tôi sẽ thử cách nó hoạt động với giao diện có thể so sánh.Hàng đợi ưu tiên Java và giao diện có thể so sánh

Đoạn Mã:

import java.util.PriorityQueue; 

class kinga implements Comparable<Double> { 
    double time=909.909; 
    double d; 

    public kinga(double a) { 
     this.d=a; 
    } 

    public int compareTo(Double d) { 
     return Double.compare(d, time); 
    } 

    public static void main(String arg[]) { 
     PriorityQueue<kinga> r=new PriorityQueue<kinga>(); 

     r.add(new kinga(4545.45)); 
     r.add(new kinga(45.4)); 
     r.add(new kinga(1235.45)); 

     System.out.println(r.poll()+" "+r.poll()+" "+r.poll()); 
    } 
} 

Nó biên dịch nhưng mang lại cho tôi ngoại lệ trong chủ đề "chính"java.lang.ClassCastException: kinga cannot be cast to java.lang.Double.

Có gì sai ở đây. Ai đó có thể cho tôi biết hàng đợi có thể so sánh và ưu tiên hoạt động như thế nào?

+0

xem câu trả lời của tôi cho mã đã chỉnh sửa và kết quả đầu ra cho giống nhau. –

Trả lời

8

kinga nên so sánh với kinga, không Double, vì vậy:

class kinga implements Comparable<kinga> 

có nghĩa là phương pháp compareTo của bạn đã được thay đổi như sau:

public int compareTo(kinga o) { 
    return Double.compare(o.d, d); 
} 
+0

Bạn có nghĩa là 'Double.compare (o.d, d)', phải không? –

+0

@ JBNizet Tôi không chắc chắn, bản gốc là 'Double.compare (d, time);', vì vậy tôi không thay đổi điều đó – Katona

+0

Nhưng nó không có ý nghĩa gì cả. –

2

PriorityQueue<kinga> sẽ mong đợi Comparable<kinga> trong phương pháp add . Đi qua một Comparable<Dobule> thay vào đó, là ném ClassCastException

8
class kinga implements Comparable<Double> 

Điều đó không có ý nghĩa. Mặc dù lớp học của bạn sẽ so sánh tốt với Double, Double là không biết điều đó, và sẽ không so sánh tốt với trường hợp của kinga, mà sẽ phá vỡ hợp đồng so sánh. Và vì một vị vua không thể so sánh với một vị vua khác, bạn không thể sử dụng số PriorityQueue<kinga>.

Nó phải là

class Kinga implements Comparable<Kinga> 

(lưu ý các hợp cụ thể trên, phải tôn trọng quy ước đặt tên Java), có nghĩa là: trường hợp Kinga có thể so sánh với nhau.

Các phương thức compareTo nên

@Override 
public int compareTo(Kinga other) { 
    return Double.compare(this.d, other.d); 
} 

có nghĩa là: Tôi lớn hơn khác Kinga nếu d của tôi là lớn hơn khác của Kinga d.

+0

bằng cách này, 'PriorityQueue 'có thể là một ví dụ khác về hy sinh an toàn kiểu cho tính linh hoạt: nếu nó được khai báo là' lớp PriorityQueue > ', thì lỗi này sẽ bị bắt tại thời gian biên dịch, nhưng chỉ có thể đặt các phần tử có thứ tự tự nhiên vào hàng đợi – Katona

+2

+1 Để lái xe về nhà, hãy xem xét 'Kinga k; Đôi d; '. Trong trường hợp này, 'k.compareTo (d);' hoạt động tốt, nhưng còn về 'd.compareTo (k) 'thì sao? Hàng đợi ưu tiên sẽ gọi sau này, đó là nguyên nhân gây ra ngoại lệ. – yshavit

0
Can somebody tell me how comparable and priority queues work? 

Đầu tiên nhận được difference giữa giao diện So sánh và So sánh.

Bây giờ cho câu hỏi của bạn, bạn có thể làm điều gì đó như dưới đây

Đầu tiên tạo một sánh cho Kinga

class comparableKinga implements Comparator<kinga> { 

@Override 
public int compare(kinga o1, kinga o2) { 
    return Double.compare(o1.getD(),o2.getD()); 
} 
} 

Sau đó tạo hàng đợi ưu tiên của bạn với Comparator này trong constructor

class kinga { 

double d; 

public kinga(double a) { 
    this.d = a; 
} 

public double getD() { 
    return this.d; 
} 

@Override 
public String toString() { 
    return "kinga{" + 
      "d=" + d + 
      '}'; 
} 

public static void main(String arg[]) { 
    PriorityQueue<kinga> r = new PriorityQueue<kinga>(11,new comparableKinga()); 


    r.add(new kinga(4545.45)); 
    r.add(new kinga(45.4)); 
    r.add(new kinga(1235.45)); 

    System.out.println(r.poll() + " " + r.poll() + " " + r.poll()); 
} 
} 

Kết quả như mong đợi

kinga{d=45.4} kinga{d=1235.45} kinga{d=4545.45} 
+0

Bạn có thể xem xét việc sử dụng PriorityQueue trong câu hỏi này không? http://stackoverflow.com/questions/28800287/how-to-restore-the-priorityqueue-to-its-initial-state-before-the-method-call?noredirect=1#comment45875800_28800287 – committedandroider

Các vấn đề liên quan