基本上,我有一個通用BST,我想爲Comparable
對象和對象使用關聯的Comparator
類。例如,我希望該樹可以與Integers
一起使用,也可以用於Point2D
,其中點可以按X方向或Y方向排序(爲此我有相應的比較器)。我想知道做這個的標準方法是什麼?我想出了這個:適用於可比較和比較器的泛型
public class Test <Data> {
public <Data extends Comparable> Test() {
System.out.println("Comparable");
this.c = null;
}
public Test(Comparator<Data> comparator) {
System.out.println("Comparator");
this.c = comparator;
}
public int compare(Data d1, Data d2) {
if (c == null) {
return ((Comparable)d1).compareTo(d2);
} else {
return this.c.compare(d1,d2);
}
}
Comparator<Data> c;
public static void main(String[] args) {
Test<Integer> test = new Test<Integer>();
System.out.println(test.compare(1,2));
Test<Point2D> test2 = new Test<Point2D>(Point2DCompare.Comparators.X);
System.out.println(test2.compare(new Point2D.Double(1,2),new Point2D.Double(2,2)));
}
}
其中Point2DCompare.Comparators.X
是,通過他們的X座標點排序一個簡單的比較。這似乎工作,但它有點難看。我想知道是否有標準的方法來解決這個問題?
編輯:實現基於user1676075:
public class Test <Data> {
public <Data extends Comparable> Test() {
dataComparator = new Comparator<Data>() {
@Override
public int compare(Data p1,Data p2) {
return p1.compareTo(p2);
}
};
}
public Test(Comparator<Data> comparator) {
dataComparator = comparator;
}
public final Comparator dataComparator;
public static void main(String[] args) {
Test<Integer> test = new Test<Integer>();
System.out.println(test.dataComparator.compare(1,2));
Test<Point2D> test2 = new Test<Point2D>(Point2DCompare.Comparators.X);
System.out.println(test2.dataComparator.compare(new Point2D.Double(1,2),new Point2D.Double(2,2)));
}
}
EDIT2:與第二個實施的一個問題是,它並不會導致編譯錯誤,如果沒有使用非可比Data
比較。例如:
Test<Point2D> test3 = new Test<Point2D>();
System.out.println(test3.dataComparator.compare(new Point2D.Double(1,2),new Point2D.Double(2,2)));
導致運行時錯誤。如果有一個完整的解決方案,這將是很好的。
另一種選擇很可能會創建一個調用的compareTo(),如果你沒有通過一個比較器,但我不確定這會是更清潔還是更高效。你有什麼看起來不錯。 – Tim 2014-09-23 19:55:15
@Tim我想我會堅持下去,直到更優雅的東西出現。 – Justin 2014-09-23 20:16:13
第二個是非常錯誤的。泛型構造函數創建一個* new *泛型類型參數'Data',它獨立於類,並隱藏類中的類型參數'Data'。因此,例如,您可以將「Data」重命名爲「Data2」。它也是不安全的,因爲創建的比較器將是'Comparator',其中'Data2'是構造函數自己的'Data',它可以是任何東西(因爲構造函數的簽名在任何參數中都不使用'Data2')。而不是班級的「數據」。但是,變量'dataComparator'必須是'比較器','Data'是類的'Data'。 –
newacct
2014-09-23 23:01:23