【问题标题】:How do I sort an array of objects of different class types?如何对不同类类型的对象数组进行排序?
【发布时间】:2016-03-20 22:59:16
【问题描述】:

我正在尝试开发一个程序,该程序可以对具有不同类类型但彼此处于相同层次结构的对象数组进行排序。所有对象都列在我要排序的同一个数组中,虽然我可以很容易地按字母顺序对相同类型的对象数组进行排序,但我无法弄清楚如何一次对所有对象进行排序Arrays.sort() 方法。任何人都可以提供任何帮助,我们将不胜感激。

import java.util.Arrays;

public class Driver {

public static void main(String[] args) {

    Vehicle[] machines = new Vehicle[3];//Example of an array that I can sort
    machines[0] = new Vehicle("Giant Robot");
    machines[1] = new Vehicle("Time Machine");
    machines[2] = new Vehicle("Airplane");
    Arrays.sort(machines);
    for (int i = 0; i < machines.length; i++)
        System.out.println(machines[i].getName());


    Vehicle[] vehicles = new Vehicle[7];//example of an array that I cannot sort
    vehicles[0] = new Car("Batmobile", 10);
    vehicles[1] = new Helicopter("Batcopter", "x");
    vehicles[2] = new Car("Jaguar", 6);
    vehicles[3] = new Helicopter("RC Copter", "t");
    vehicles[4] = new Car("Accelerator", 6);
    vehicles[5] = new Helicopter("Stormshadow", "z");
    vehicles[6] = new Car("Batmobile", 11);
}

}

**

public class Vehicle implements Comparable {
private String name;

public Vehicle(){
    name = "no name";
}

public Vehicle(String newName){
    name = newName;
}

public String getName(){
    return name;
}

public int compareTo(Object o)
{
    if ((o != null) &&
        (o instanceof Vehicle))
    {
        Vehicle otherVehicle = (Vehicle) o;
        return (name.compareTo(otherVehicle.name));
    }
    return -1;
}

}

**

public class Car extends Vehicle {

private int tireSize;

public Car(){
    super();
    tireSize = 0;
}

public Car(String newName, int newTireSize){
    super(newName);
    tireSize = newTireSize;
}

public int getSize(){
    return tireSize;
}

}

**

public class Helicopter extends Vehicle {

private String bladeType;

public Helicopter(){
    super();
    bladeType = "none";
}

public Helicopter(String newName, String newBlade){
    super(newName);
    bladeType = newBlade;
}

public String getType(){
    return bladeType;
}

}

【问题讨论】:

  • 你为什么要实现Comparable而不是Comparable&lt;? extends Vehicle&gt;
  • @Tom 如果您的问题得到解决,您可以接受/投票赞成答案,那就太好了。来自here,“接受答案很重要,因为它既奖励海报解决您的问题,又通知其他人您的问题已解决。”
  • 我的问题还没有解决,但我会在我的代码正常工作后立即投票给答案(希望很快)。
  • @Tom,很难弄清楚你遇到了什么问题,所以你有一堆答案,对此有不同的猜测。您可能想解释为什么每个都不满足。我的猜测不同——我想你想知道一种叫做“双重调度”的模式:en.wikipedia.org/wiki/Double_dispatch
  • 我自己也反对这个。找到任何解决方案了吗?

标签: java sorting hierarchy compareto


【解决方案1】:

目标:您需要能够将Vehicle 与其他Vehicle 进行比较。

为实现该目标:

public class Vehicle implements Comparable<? extends Vehicle> {

    ....

    public int compareTo(Object o) {
        // Now, that the Comparable is for the type Vehicle
        // you know that o is some kind of vehicle

        // check vehicle related things
        // number of seats, dogs, whatever
        return -1;
    }

}

【讨论】:

    【解决方案2】:

    您只需将代码调整为:

    class Vehicle implements Comparable<Vehicle> {
    
        private String name;
    
        /* ... */
    
        @Override
        public int compareTo(Vehicle vehicle) {
            return name.compareTo(vehicle.getName());
        }
    }
    

    【讨论】:

      【解决方案3】:

      在大多数情况下,你的类不应该实现Comparable,除非有一个且只有一个总是正确的排序,比如数字。您的车辆可以按名称、年龄以及可能更多的标准进行排序,因此它们不应实现Comparable

      相反,您可以在实际对车辆进行排序时将排序函数作为 lambda 函数传递:

      Arrays.sort(machines, (left, right) -> left.getName().compareTo(right.getName()));
      

      或者,等效地:

      Arrays.sort(machines, Comparator.comparing(Vehicle::getName));
      

      这样你就不再需要implements Comparable了。

      【讨论】:

        【解决方案4】:

        如果要按车辆类型排序,则需要在对元素进行排序时考虑类类型。修改compareTo()方法如下图:

        public int compareTo(Object o){
            if ((o != null) &&
                (o instanceof Vehicle)){
                Vehicle otherVehicle = (Vehicle) o;
                return (otherVehicle.getClass().getSimpleName().equals(this.getClass().getSimpleName()) ? 
                        name.compareTo(otherVehicle.name) 
                        : otherVehicle.getClass().getSimpleName().compareTo(this.getClass().getSimpleName()));
            }
            return -1;
        }
        

        【讨论】:

        • o != null 是多余的,因为instanceof 会检查null。 • 为了性能和可读性,每个对象只能调用一次getSimpleName 方法。 • 默认情况下返回-1 是错误的,因为它通常会阻止compareTo 反对称。 • 参数类型应为Vehicle 而不是Object
        猜你喜欢
        • 2021-10-11
        • 2021-02-18
        • 2019-10-17
        • 2016-05-21
        • 2022-01-20
        • 1970-01-01
        • 2020-02-23
        • 2017-07-03
        • 2016-04-17
        相关资源
        最近更新 更多