【问题标题】:Java sort any array of objectsJava 对任何对象数组进行排序
【发布时间】:2013-03-15 13:21:53
【问题描述】:

我已经定义了一个抽象类如下:

public abstract class Move implements Comparable<Move> {
protected int cell;
protected int weight;       

public int getWeight()
{
    return this.weight;
}

public void setWeight(int value)
{
    this.weight = value;
}

protected Move(int cell)
{
    this.cell = cell;
    this.weight = 0;
}

protected Move(int cell, int weight)
{
    this.cell = cell;
    this.weight = weight;
}

@Override
public int compareTo(Move m) 
{
    return this.weight - m.weight;
}

我还有另外 2 个类扩展了这个类(分类为 MoveLeft 和 MoveRight)。我将这两种类型的对象都添加到 Move 类型的 List 中,然后使用 Collections.sort 进行排序:

List<Move> moves = new ArrayList<Move>(someSize);
moves.add(new MoveLeft(cell1));
moves.add(new MoveRight(cell2));
moves.add(new MoveRight(cell3));
moves.add(new MoveLeft(cell4));
Collections.sort(moves);

但是,列表是按单元格而不是按重量排序的。

不能在同一个排序中混合不同的子类实例吗?

注意:我在子类构造函数中为权重设置了一个唯一值。

【问题讨论】:

  • 子类是否覆盖 compareTo?
  • 不是所有的权重值都是0,因为你只使用构造函数设置cell-value而不使用setWeight()?
  • 在我看来,你所有的权重都是 0,所以排序顺序是任意的......(似乎@ghdalum 也注意到了,早 2 秒 ;-))
  • @Heuster 第二名只是第一个失败者:)
  • @Heuster Collections.sort 用于引用是稳定的,因此排序顺序不是任意的。如果所有 compareTo 调用都返回 0,则保留原始顺序。

标签: java sorting collections


【解决方案1】:

您必须创建 Move 数组,并使用派生类将其向上转换为 Move 并像往常一样对其进行排序,然后您可以使用 istanceOf 和 downcast 检查您的实际类。

【讨论】:

  • 不需要强制转换:Collections.sort() 方法不需要。在这种情况下,它将看到对象实现 Comparable 并调用 compareTo() 方法,而不管数组类型或保存实例的引用类型。
【解决方案2】:

这真的是一个很长的评论,而不是一个答案。

我编写了一个简单的测试程序,它似乎可以正确排序。输出为[Move [cell=10, weight=1], Move [cell=1, weight=100]],既不是我添加元素的顺序,也不是单元格升序,而是权重升序。

我注意到您有两个相同类型的构造函数参数。我建议非常仔细地检查它们是否没有被调换。如果这不是问题,我建议尝试修改我的测试程序,使其更类似于真实代码,直到它重现问题为止。这是我的测试程序:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
  public static void main(String[] args) {
    List<Move> list = new ArrayList<Move>();
    list.add(new MoveRight(1, 100));
    list.add(new MoveLeft(10, 1));
    Collections.sort(list);
    System.out.println(list);
  }
}

abstract class Move implements Comparable<Move> {
  protected int cell;
  protected int weight;

  public int getWeight()
  {
    return this.weight;
  }

  public void setWeight(int value)
  {
    this.weight = value;
  }

  protected Move(int cell)
  {
    this.cell = cell;
    this.weight = 0;
  }

  protected Move(int cell, int weight)
  {
    this.cell = cell;
    this.weight = weight;
  }

  @Override
  public int compareTo(Move m)
  {
    return this.weight - m.weight;
  }

  @Override
  public String toString() {
    return "Move [cell=" + cell + ", weight=" + weight + "]";
  }
}

class MoveLeft extends Move {

  protected MoveLeft(int cell, int weight) {
    super(cell, weight);
  }

}

class MoveRight extends Move {

  protected MoveRight(int cell, int weight) {
    super(cell, weight);
  }

}

【讨论】:

  • 这样做了,我还确保每个重量值都是唯一的。它仍然按单元格对对象进行排序
  • @Ivan-MarkDebono 在这种情况下,我认为您最好的方法是使用SSCCE,或者通过添加到我的测试程序或剥离您的真实代码。
猜你喜欢
  • 1970-01-01
  • 2021-04-15
  • 2013-11-03
  • 2011-08-18
相关资源
最近更新 更多