如何在不知道类型的情况下比较两个对象

How to compare two objects without knowing their type

我正在实现一个排序列表 class,在这个 class 中,我将对任何类型的对象进行排序,所以现在我想测试该对象是否具有可比性,

我用这段代码覆盖了 compareTo() 方法:-

class MyObject implements Comparable {

Object ob;

    MyObject(){
        this.ob=new Object();
    }

    public int compareTo(Object current){
        if((ob.toString().compareTo(current.toString()))>1)
        return 1;
        else if((ob.toString().compareTo(current.toString()))<1)
        return -1;
        else
        return 0;

    }

    public String toString(){

        return (String)ob;
    }
}

所以现在我需要像这样为这些对象分配编号

class SortedListTest{
    public static void main (String arg[]){

        MyObject b1= new MyObject();
        MyObject b2= new MyObject();

        b1.ob=6;
        b2.ob=3;

        System.out.println(b2.compareTo(b1));
    }

}

但它一直给我这个例外:-

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

从概念上讲,这根本没有意义!

要点是:当您允许在列表中使用任意类型的对象时,"sorting" 的概念在这里 而不是 有意义。

因此简短的回答是:算了吧。

从技术上讲,您的问题在这里:

return (String)ob;

该代码假定obj 是一个字符串。但是当你允许 any 类型的对象时,这不一定是正确的。所以 obj.toString() 可以防止运行时问题,但是;如前所述:解决该技术问题并不是真正的答案。

让我们回到现实世界的例子:假设您被要求对 table 上的东西进行分类:勺子、刀、杯子、香蕉、苹果。你打算怎么做?

如果有的话,您可以撤回一些共同点;例如 "weight"。所以你把所有的东西都放在一个秤上;并将其用于 "sort" 他们。

从 Java 的角度来看,对象的 唯一 的共同点是字符串表示(在对它们调用 toString() 时)或数值(调用 hashCode() 时)。因此,您可以 "sort" 在这些属性上。哪个可行,但不会产生任何有用的东西。

换句话说:当您打算 排序 列表的内容时,除了允许列表中的 "same kind of objects" 之外别无他法。这就是 java 集合以这种方式工作的原因。在某种意义上:一个人使用泛型来表达 List<T> 包含具有某些 common 类型的对象。从概念的角度来看,这只是意味着:不是允许 任何东西 进入特定列表,而是只允许 "have something in common" 的对象。

您报告的问题是

return (String)ob;

应该是

return ob.toString();

如果 ob 永远不会为空;或

return Objects.toString(ob);

如果可能的话。


但请注意,将对象包装在对象中以比较其 toString() 并不是必需的。你可以简单地使用一个 Comparator<Object>,就像 Guava 的 Ordering.usingToString():

int order = Ordering.usingToString().compare(someObject, someOtherObject);

或 Java 8 等价物。我想应该是这样的:

Comparator<Object> usingToString = (a, b) -> a.toString().compareTo(b.toString());
int order = usingToString(someObject, someOtherObject);

在Java中,int是原始类型。原始类型没有方法。所以当你这样做的时候。

b1.ob = 6;
b2.ob = 3;

您正在将一个整数放入 MyObject class 的 ob 变量中。在 compareTo(Object current) 方法中,您调用 ob 上的 toString() 方法。因为你给了 ob 一个整数,你不能调用它的任何方法;

在不知道对象类型的情况下对对象进行排序在许多情况下没有意义。但是,在某些情况下,您可能希望按类型等对对象进行分组(尽管像地图等不同类型的存储可能更适合这种情况)。

问题在于,如果不知道对象的类型,您的操作就会受到限制。您的比较器可以执行以下操作:

  • 检查正在比较的对象是否实现 Comparable 并调用其中一个的 compareTo() 方法。
  • 如果它们相同 type/class 那么它们可能相等也可能不相等(取决于您的要求)。如何比较取决于你。
  • 如果类型不同,您可以尝试通过 class 名称等进行比较。

也就是说你应该真的想想你是否真的需要它,因为你可以依赖的信息很少上。