2016-01-04 21 views
2

上執行下面提到的代碼,我得到我們如何使用不同種類的鑰匙在TreeMap中

Exception in thread "main" java.lang.ClassCastException: com.test.tree.T1 cannot be cast to com.test.tree.T2 
    at com.test.tree.TestComparator.compare(TestTreeMap.java:59) 
    at java.util.TreeMap.put(TreeMap.java:530) 
    at com.test.tree.TestTreeMap.main(TestTreeMap.java:22) 

代碼:

package com.test.tree; 

import java.util.Comparator; 
import java.util.TreeMap; 

public class TestTreeMap{ 

    public static void main(String[] args) { 

     TreeMap tree=new TreeMap(new TestComparator()); 
     T1 t1=new T1(10, 20); 
     T2 t2=new T2(10,21); 
     tree.put(t1, 23); 
     tree.put(t2, 24); 
    } 

} 
class T1 { 
    int x,y; 

    public T1(int x, int y) { 
    super(); 
    this.x = x; 
    this.y = y; 
} 


} 
class T2 { 
    int x,y; 
    public T2(int x,int y) { 
     super(); 
     this.x = x; 
     this.y = y; 
} 

} 

class TestComparator implements Comparator{ 

    @Override 
    public int compare(Object o1, Object o2) { 
     System.out.println("hi im called"); 
     T1 t1=(T1)o1; 
     T2 t2=(T2)o2; 
     return t1.x-t2.y; 
     } 

} 

回答

3

你不能假設compare總是會收到一個T1實例作爲第一個參數和T2實例。它可能會收到兩個T1實例或兩個T2實例或兩者的實例,但不是按您的預期順序。

在將它們投射到T1T2之前,您必須測試o1o2的類型。

@Override 
public int compare(Object o1, Object o2) { 
    if (o1 instanceof T1) { 
     if (o2 instanceof T2) { 
      T1 t1=(T1)o1; 
      T2 t2=(T2)o2; 
      return t1.x-t2.y; 
     } else { 
      ... 
     } 
    } else { 
     ... 
    } 
} 

這是假設的鑰匙你TreeMap只能爲T1T2

+0

感謝@Eran,我是有點困惑 – JavaStack

+0

但如果有多種類型的候選關鍵.......那麼任何通用的方法來做到這一點? – JavaStack

1

有兩個獨立的clases沒有點至今,只需使用:T2

public static void main(String[] args) { 

    TreeMap tree=new TreeMap(new TestComparator()); 
    T1 t1=new T1(10, 20); 
    T1 t2=new T1(10, 21); 
    tree.put(t1, 23); 
    tree.put(t2, 24); 
} 

或繼承類從T1類及用途:

class TestComparator implements Comparator{ 

    @Override 
    public int compare(Object o1, Object o2) { 
     System.out.println("hi im called"); 
     T1 t1=(T1)o1; 
     T1 t2=(T1)o2; 
     return t1.x-t2.y; 
    } 

} 

或宣佈一些正式的接口,它必須可以通過T1T2兩個類來實現,並且無論參數是什麼都可以處理比較:

interface Comparable { 
    int comparisonToken(); 
} 

class T1 implements Comparable { 
    int comparisonToken() { 
     return this.x; 
    } 
    ... 
} 

class T2 implements Comparable { 
    int comparisonToken() { 
     return this.y; 
    } 
    ... 
} 

class TestComparator implements Comparator{ 

    @Override 
    public int compare(Object o1, Object o2) { 
     System.out.println("hi im called"); 
     Comparable t1= (Comparable)o1; 
     Comparable t2= (Comparable)o2; 
     return t1.comparisonToken() - t2.comparisonToken(); 
    } 

} 
+0

請加上仿製藥;使用這樣的原始類型不是一個好主意。 –

+0

@ankhzet可能有一些場景,我們必須使用多種類型的對象作爲關鍵 – JavaStack

+0

然後,你應該爲它們定義一些基本的可比較接口,並在比較器中使用它,如我所建議的 – ankhzet

0

使用下面的代碼:

@Override 
    public int compare(Object o1, Object o2) { 
     System.out.println("hi im called"); 
     T1 t1 = null; 
     T2 t2 = null; 
     if(o1 instanceof T1){ 
      t1=(T1)o1; 
     } else if(o1 instanceof T2){ 
      t2 = (T2)o1; 
     } 
     if(o2 instanceof T2){ 
      t2=(T2)o2; 
      return t1.x-t2.y; 
     } else{ 
      t1 = (T1)o2; 
      return t1.x-t1.y; 

     } 

     }