如何在TreeMap中使用异构密钥

  • 本文关键字:异构 密钥 TreeMap java
  • 更新时间 :
  • 英文 :


在执行下面提到的代码时,我得到了

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

您不能假设compare将始终接收一个T1实例作为第一个参数,而T2实例作为第二个参数。它可能会接收两个T1实例或两个T2实例,或者同时接收这两个实例,但不是按照您期望的顺序。

在将o1o2类型强制转换为T1T2之前,必须测试它们的类型。

@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

到目前为止,在两个独立的类中没有任何意义,只需使用:

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继承类T2并使用:

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

使用以下代码:

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

最新更新