如何比较两个对象而不知道它们的类型

时间:2017-01-20 08:26:03

标签: java object compareto

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

我使用此代码覆盖 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));
    }

}

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

  

线程“main”中的异常java.lang.ClassCastException:   java.lang.Integer无法强制转换为java.lang.String

4 个答案:

答案 0 :(得分:6)

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

关键是:当你在列表中允许任意类型的对象时,那么概念&#34;排序&#34; 在这里有意义吗?

因此简短的回答是:忘掉它。

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

return (String)ob;

该代码假定 obj是一个String。但是,当您允许任何类型的对象时,这不一定是真的。所以obj.toString()会阻止运行时问题,但是;如上所述:解决技术问题并不是真正的答案。

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

如果有的话,你可以收回所有共同点的东西;喜欢&#34;体重&#34;例如。所以你把所有东西放在一个尺度上;并用它来排序&#34;他们。

从Java的角度来看,对象共有的唯一事物是String表示(当对它们调用toString()时)或数值(调用{{1}时) })。因此你可以&#34;排序&#34;在那些属性上。哪个会起作用,但不会导致任何远程有用的东西。

换句话说:当您打算排序列表的内容时,除了只允许&#34;相同类型的对象之外别无选择。在你的清单中。这就是为什么java集合正是以这种方式工作的原因。在以下意义上:使用泛型来表示hashCode()包含具有某些 common 类型的对象。从概念的角度来看,这仅仅意味着:不是允许任何进入特定列表,而是只允许具有共同点的对象&#34;。

答案 1 :(得分:3)

您报告的问题是

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

答案 2 :(得分:1)

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

问题在于不知道对象&#39;您可以做的事情类型有限。您的比较器可以执行以下操作:

  • 检查被比较的对象是否实施Comparable并在其中调用compareTo()方法。
  • 如果它们属于同一类型/类别,那么它们可能相同或不同(取决于您的要求)。如何比较这些取决于你。
  • 如果类型不同,您可以尝试按类名等进行比较。

有人说你应该真的考虑你实际是否需要它,因为你可以依赖的小信息很难。

答案 3 :(得分:-2)

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

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

您正在MyObject变量的ob类中添加一个int。在compareTo(Object current)方法中,您可以在toString()上调用ob方法。由于你给了ob一个int,你不能调用任何方法;