java 将不同类型的对象与可比对象进行比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11901072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 06:50:41  来源:igfitidea点击:

Comparing different type of Objects with comparable

javalistcollectionscomparable

提问by pankar

A.java

A.java

public class A implements Comparable {
    private String id;
    private String name;

    public A(String a, String b) {
        id = a;
        name = b;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int compareTo(Object o) {
        A a = (A) o;
        return id.compareTo(a.getId());
    }
}

B.java

B.java

public class B implements Comparable {
    private String b_id;
    private String other;

    public B(String a, String b) {
        b_id = a;
        other = b;
    }

    public String getBId() {
        return b_id;
    }

    public void setBId(String id) {
        this.b_id = id;
    }

    public String getOther() {
        return other;
    }

    public void setOther(String other) {
        this.other = other;
    }

    public int compareTo(Object o) {
        B b = (B) o;
        return b_id.compareTo(b.getId());
    }
}

Learn.java

Learn.java

public class Learn {

    public static void main(String[] args) {

        List<A> listA = new ArrayList<A>();
        List<B> listB = new ArrayList<B>();
        List<Object> listAll = new ArrayList<Object>();
        listA.add(new A("aa", "bb"));
        listA.add(new A("ae", "bbn"));
        listA.add(new A("dfr", "GSDS"));
        listB.add(new B("nm", "re"));
        listB.add(new B("asd", "asfa"));

        listAll.addAll(listA);
        listAll.addAll(listB);
        Collections.sort(listAll);
        for (Object o : listAll) {
            if (o instanceof A)
                System.out.println(o.getId);
            else if (o instanceof B)
                Syatem.out.println(o.getBId);
        }

    }

}

The error i get is at the line Collections.sort(listAll);It says.

我得到的错误是Collections.sort(listAll);它说的那一行。

Bound mismatch: The generic method sort(List<T>) of type Collections is not applicable
for the arguments (List<Object>). The inferred type Object is not a valid substitute
for the bounded parameter <T extends Comparable<? super T>>

What to do? Also is the rest of the logic all right?

该怎么办?其余的逻辑也没有问题吗?

What i am trying to do is have a list of A and list of B with one attribute same as id; though the variable name is not the same. i.e idin Aand bidin B. Now i put both the lists in ListAll and do sort on them on the same variable id/bid. I have A and B implementing Comparable.

我想要做的是有一个 A 列表和 B 列表,其中一个属性与 id 相同;虽然变量名不一样。即idAbid在现在B.我在ListAll把两个列表和它们的排序上做相同的变量ID /投标。我有 A 和 B 实现 Comparable。

and my listAll is of type Object?

而我的 listAll 是 Object 类型?

how do I do it? thanks.

我该怎么做?谢谢。

回答by Nicola Musatti

You could add a common base class and implement comparison there, as in:

您可以添加一个公共基类并在那里实现比较,如下所示:

abstract class AandBComparable implements Comparable {

  public int compareTo(Object o) {
    AandBComparable ab = (AandBComparable) o;
    return getId().compareTo(ab.getId());
  }

  public abstract String getId();
}

回答by JB Nizet

To be able to sort a list, its elements must be comparable to each other. That's not the case here. Instances of A can only be compared with other instances of A. Same for B.

为了能够对列表进行排序,其元素必须相互比较。这不是这里的情况。A 的实例只能与 A 的其他实例进行比较。 B 也是如此。

If you want to sort a list containg A and B instances, you need to provide Comparatorwhich will happily take two As, two Bs or an Aand a B, and compare these objects as you want them compared.

如果您想对包含 A 和 B 实例的列表进行排序,您需要提供Comparator哪一个将很乐意接受两个As、两个Bs 或 anA和 a B,并根据需要比较这些对象。

public class AOrBComparator implements Comparator<Object> {
    @Override
    public int compare(Object o1, Object o2) {
        String o1Id = getId(o1);
        String o2Id = getId(o2);
        return o1Id.compareTo(o2Id);
    }

    private String getId(Object o) {
        if (o instanceof A) {
            return ((A) o).getId();
        }
        else if (o instanceof B) {
            return ((B) o).getId();
        }
        else {
            throw new IllegalArgumentException("Can only get ID from A or B");
        }
    }
}

But maybe A and B should implement the same Identifiable interface, and the list should be a List<Identifiable>. This way, you could easily write a comparator that compares two instances of Identifiable, and it would work whether the actual instance is A, B, or any other Identifiable.

但也许 A 和 B 应该实现相同的 Identifiable 接口,并且列表应该是List<Identifiable>. 这样,您可以轻松编写一个比较器来比较 Identifiable 的两个实例,无论实际实例是 A、B 还是任何其他 Identifiable,它都可以工作。

回答by pankar

You need a base (dummy) class which will implement Comparableand let A and B derive from class. Something like:

您需要一个基础(虚拟)类,它将实现Comparable并让 A 和 B 从类派生。就像是:

public abstract class MyComparableClass implements Comparable {
}

public class A extends MyComparableClass {
... // implementation of compareTo
}

public class B extends MyComparableClass {
...// implementation of compareTo
}

In your main program then simply define the Collection to be:

在您的主程序中,只需将 Collection 定义为:

List<MyComparableClass> listAll = new ArrayList<MyComparableClass>();

回答by SJuan76

I do not believe the exception raises where you tell, but rather in a call to sort()

我不相信异常会在你告诉的地方引发,而是在调用 sort()

Anyway, it means something like

无论如何,这意味着类似

"The sort method expects a Listof elements that implement comparable. But you tell him that you are giving a list of Object, and not all Object implement Comparable. So, the compiler cannot be sure that at realtime the objects passed in the list will implement Comparable (as required), and throws an error"

“ sort 方法需要一个List实现可比较的元素。但是你告诉他你给出了一个列表Object,而不是所有的 Object 都实现了 Comparable。所以,编译器不能确定在列表中传递的对象实时将实现 Comparable (根据需要),并引发错误”

The solution? Define the list with a bound class that implements Comparable

解决方案?使用实现 Comparable 的绑定类定义列表

 List<A> listAll = new ArrayList<A>(); 

Update: To have all items in the same list then either:

更新:要将所有项目都放在同一个列表中,然后:

a) Have all items derive from a common class / interface that implements Comparable. Usually this would be the most Object Oriented Programming friendly approach, since if you want to compare both classes they must be somehow related. Either extend B from A, A from B, A and B from another class, or make A and B implement another interface (which itself implements Comparable).

a) 让所有项目都派生自一个实现Comparable. 通常这将是对面向对象编程最友好的方法,因为如果您想比较两个类,它们必须以某种方式相关。要么从 A 扩展 B,从 B 扩展 A,从另一个类扩展 A 和 B,要么让 A 和 B 实现另一个接口(它本身实现了 Comparable)。

b) As JBNizet said, use a Comparator.

b) 正如 JBNizet 所说,使用Comparator.

Again, I strongly recommend using the a solution.

同样,我强烈建议使用 a 解决方案。