Beim Ausführen des unten genannten Codes erhalte ich

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)

Code:

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;
        }

}
2
JavaStack 4 Jän. 2016 im 15:37

3 Antworten

Beste Antwort

Sie können nicht davon ausgehen, dass compare immer eine T1 Instanz als erstes Argument und eine T2 Instanz als zweites Argument erhält. Es kann zwei T1 Instanzen oder zwei T2 Instanzen oder Instanzen von beiden empfangen, jedoch nicht in der von Ihnen erwarteten Reihenfolge.

Sie müssen die Typen o1 und o2 testen, bevor Sie sie in T1 oder T2 umwandeln.

@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 {
        ...
    }
}

Dies setzt voraus, dass die Schlüssel Ihres TreeMap nur entweder T1 oder T2 sein können.

3
Eran 4 Jän. 2016 im 12:39

Bisher macht es keinen Sinn, zwei getrennte Klassen zu verwenden. Verwenden Sie einfach:

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);
}

Oder erben Sie die Klasse T2 von der Klasse T1 und verwenden Sie:

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;
    }

}

Oder deklarieren Sie eine formale Schnittstelle, die sowohl von T1 als auch von T2 Klassen implementiert werden muss und die fehlerfreie Verarbeitung von Vergleichen ermöglicht, unabhängig von den Argumenten:

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();
    }

}
1
ankhzet 4 Jän. 2016 im 12:45

Verwenden Sie den folgenden Code:

 @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;

        }

        }
0
Vineet Kasat 4 Jän. 2016 im 13:05