【问题标题】:Sort ArrayList of objects that are instance of sub classes of abstract class对作为抽象类的子类实例的对象的 ArrayList 进行排序
【发布时间】:2017-10-21 06:55:41
【问题描述】:

这是我的主要结构: 一些接口方法在A类中实现,其余的都在子类中实现。

public interface I
{
// some methods
//
}

public abstract class A implements I
{
// some variables and methods
//
}

public class B extends A
{
// some variables and methods
//
}

public class C extends A
{
// some variables and methods
//
}

public abstract class D extends A
{
// some variables and methods
//
}

public class E extends D
{
// some variables and methods
//
}

public class Test
{
 public static void main(String[] args) 
 {
  ArrayList<I> la = new ArrayList<I>();
  la.add(new B(..));
  la.add(new C(..));
  la.add(new C(..));
  la.add(new B(..));
  la.add(new E(..));
 }
}

B、C、E类都有构造函数。

我需要按A类的变量对la进行排序,变量是int数据类型。

我试着改成

public abstract class A implements I, Comparable<A>

但由于在所有非抽象类中缺少 public int compareTo(A o) 方法,我得到一个错误。

我需要做什么?

谢谢。

【问题讨论】:

  • 如果缺少某些东西,那么添加缺少的实体的想法如何。
  • 类对象的排序是基于您的逻辑的。 JVM 不能神奇地为你定义它。你需要在某个地方定义它。如果实现 Comparable 接口,则需要在其抽象方法compareTo 的implwmwntation 中定义比较逻辑,您必须提供该方法的实现。添加它,实现比较逻辑。可能是您将能够解决问题,或者您将有更多有意义和具体问题。
  • 所以我需要在 A 类中实现 public int compareTo(A o) ?
  • 如果可以的话,在A中实现,那么你只需要写一次。您也可以在 B、C 和 E 中实现,或者只是在其中一个类中覆盖它,但我无法想象您为什么想要或需要这样做。
  • 我怎样才能只在class A中实现这个方法。我在class A 中没有构造函数,所以我不知道该怎么做。在 void main 我使用Collections.sort。谢谢。

标签: java sorting arraylist comparator comparable


【解决方案1】:
public abstract class A implements I, Comparable<A> {
    // some variables and methods

    @Override
    public int compareTo(A o) {
        return someVariable - o.someVariable;
    }
}

您不需要 A 中的构造函数来实现 compareTo 方法,并且您有一些变量可以用于比较。 compareTo 只是一个方法,所以既然你可以在 A 中有方法,那么你也可以有一个 compareTo 方法。由于我不知道你有什么变量,也不知道你需要的排序顺序,所以你必须自己填写方法。

另一方面,在 A 中有一个构造函数可能是个好主意,但这是一个完全独立的问题。

编辑:一开始我没有想到这一点:你当然会想要这样做

    Collections.sort(la);

这并不像听起来那么简单。 Collections.sort() 是根据the docs 声明为的泛型方法:

static <T extends Comparable<? super T>> void sort(List<T> list)

这意味着为了让编译器对方法的调用感到满意,列表的声明元素类型必须是实现 Comparable&lt;U&gt; 的类型 U 的元素类型或超类型它。你的元素类型是I,而I 没有实现Comparable。这就是您收到错误消息的原因。

解决方案?我认为不存在完美的解决方案。假设您不想声明 la 和 ArrayList&lt;A&gt;,另一种选择是声明 I 是可比较的:

public interface I extends Comparable<I>

严格来说,A 的承诺比我们所能实现的要多。我们可以比较两个A 对象(即使它们是A 的子类的实例),但I 可能还有其他实现,我们可能不知道如何将它们与A 进行比较。一种出路是:

@Override
public int compareTo(I o) {
    A oa = (A) o; // will throw ClassCastException if o is not an A
    return someVariable - oa.someVariable;
}

由于A 扩展I 和I 扩展Comparable&lt;I&gt;,我们现在必须声明o 和I,而不是A。如果有人给我们一些国外的I 实现,我们会抛出一个ClassCastException,然后排序会将其传播给调用者。但是,我们知道在您的列表中,所有元素都是 A 的子类的实例,因此不会发生这种情况。使用上述方法,您对S.sortBySome() 的调用和对Collections.sort() 的调用都将起作用。

【讨论】:

  • 我将此方法添加到类 A。来自 main 的 arraylist la,我将它传递给包中​​另一个类的静态方法。在主要方法中,我使用 foreach 按某个变量按排序顺序打印所有实例。 public class S { public static ArrayList&lt;String&gt; sortBySome(ArrayList&lt;I&gt; la) { } } 所以我将它添加到方法中:` ArrayList obj = new ArrayList(); Collections.sort(la); ` 但是我在排序方法上遇到错误。 The method sort(List&lt;T&gt;) in the type Collections is not applicable for the arguments (ArrayList&lt;I&gt;)这是为什么呢?
  • 我收到同样的错误信息。请参阅我的编辑以获取解释和绕过它的一种方法。
【解决方案2】:

我通过添加解决了它 public interface I extends Comparable&lt;I&gt; 在 A 类中,我将方法 compareTo 更改为

public int compareTo(I obj)
{
    return someVariable - obj.someVariable;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多