如何在Java中对包含两个以上异构对象的List进行排序?

时间:2018-10-27 08:57:11

标签: java

嗨,我有一个对象列表,其中包含四个对象(员工,学生,患者,客户)。我需要根据它们对应的ID以升序对这些列表进行排序。 当我使用Collections.sort(list)方法时,会给出 ClassCastException

下面是我正在使用的完整代码...

注意:我也尝试使用Comparator接口,但是无法在compare()方法内部定义逻辑来对这些对象进行排序。如果列表包含两个对象,则很容易在其中定义对这些对象排序的逻辑,但是如果列表包含两个以上的对象,则很难在compare()方法内定义排序逻辑。

有人可以帮助我缩短此列表吗? 请修改以下代码,然后为我提供解决方案。输出应按[10,20,30,40,50,60,70,90]等排序顺序

public class Test
{
    public static void main(String[] args)
    {
        List list = new ArrayList();
        list.add(new Employee(50));
        list.add(new Customer(10));
        list.add(new Patient(60));
        list.add(new Student(90));
        list.add(new Employee(20));
        list.add(new Customer(40));
        list.add(new Patient(70));
        list.add(new Student(30));

        Collections.sort(list);
        System.out.println(list);

    }
}

class Patient implements Comparable<Patient>
{

    int pId;

    Patient(int pId)
    {
        this.pId = pId;
    }

    @Override
    public int compareTo(Patient o)
    {
        return this.pId - o.pId;
    }

    @Override
    public String toString()
    {
        return this.pId + "";
    }

}

class Employee implements Comparable<Employee>
{

    int empId;

    Employee(int empId)
    {
        this.empId = empId;
    }

    @Override
    public int compareTo(Employee o)
    {
        return this.empId - o.empId;
    }

    @Override
    public String toString()
    {
        return this.empId + "";
    }

}

class Customer implements Comparable<Customer>
{

    int cId;

    Customer(int cId)
    {
        this.cId = cId;
    }

    @Override
    public int compareTo(Customer o)
    {
        return this.cId - o.cId;
    }

    @Override
    public String toString()
    {
        return this.cId + "";
    }

}

class Student implements Comparable<Student>
{

    int sId;

    Student(int sId)
    {
        this.sId = sId;
    }

    @Override
    public int compareTo(Student o)
    {
        return this.sId - o.sId;
    }

    @Override
    public String toString()
    {
        return this.sId + "";
    }

}

4 个答案:

答案 0 :(得分:3)

使用方法Identifiable定义接口int getId()(或超类Person)。

使所有类都实现该接口(或扩展该超类)。

停止使用原始类型,因此使用List<Identifiable>代替List

然后使用Comparator<Identifiable>对列表进行排序,可以使用Comparator.comparingInt(Identifiable::getId)进行定义。

您所有的类都不应实现Comparable。他们的ID并未定义其自然顺序。您只是碰巧在此特定用例中按ID对它们进行了排序。因此,应使用特定的比较器。

答案 1 :(得分:1)

定义一个超类,例如Person,然后在其中添加id。基于id逻辑的比较也应该在那里实现。

public class Person implements Comparable<Person> {

    private int id;

    // getters, setters, compareTo, etc

}

使所有基类都从Person扩展

public class Student extends Person { ... }
public class Customer extends Person { ... }
public class Employee extends Person { ... }
public class Patient extends Person { ... }

根据List的定义Person并对其进行排序。

public static void main(String[] args)
{
    List<Person> list = new ArrayList<>();
    list.add(new Employee(50));
    list.add(new Customer(10));
    list.add(new Patient(60));
    list.add(new Student(90));
    list.add(new Employee(20));
    list.add(new Customer(40));
    list.add(new Patient(70));
    list.add(new Student(30));

    Collections.sort(list);
    System.out.println(list);
}

答案 2 :(得分:0)

创建具有id属性的类之类的类。然后通过它扩展所有这些类。然后,您只需要为人类编写比较

答案 3 :(得分:0)

只需为所有POJO添加一个公共接口,定义一个获取ID的方法,然后编写一个自定义比较器进行比较,即可轻松实现此目的。

这里是对对象进行排序的重写版本。

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


class Test {    

public static void main(String[] args) {
    List list = new ArrayList();
    list.add(new Employee(50));
    list.add(new Customer(10));
    list.add(new Patient(60));
    list.add(new Student(90));
    list.add(new Employee(20));
    list.add(new Customer(40));
    list.add(new Patient(70));
    list.add(new Student(30));

    Collections.sort(list, new IDComparator());

    Stream.of(list).forEach(System.out::println);

}
}


class Patient implements CommonObject {

int pId;

Patient(int pId) {
    this.pId = pId;
}


@Override
public int getId() {
    return this.pId;
}
}

class Employee implements CommonObject {

int empId;

Employee(int empId) {
    this.empId = empId;
}

@Override
public int getId() {
    return this.empId;
}


}

class Customer implements CommonObject {

int cId;

Customer(int cId) {
    this.cId = cId;
}


@Override
public int getId() {
    return this.cId;
}

}

class Student implements CommonObject {

int sId;

Student(int sId) {
    this.sId = sId;
}

@Override
public int getId() {
    return this.sId;
}

}

现在是自定义比较器:

import java.util.Comparator;


public class IDComparator implements Comparator<CommonObject> {

@Override
public int compare(CommonObject o1, CommonObject o2) {
    if (o1.getId() == o2.getId())
        return 0;
    else if (o1.getId() > o2.getId())
        return 1;
    else
        return -1;
}
}

公共对象接口:

public interface CommonObject {
int getId();
}

经过测试,以下是上述代码的输出:

  

[Customer @ 23223dd8,Employee @ 4ec6a292,Student @ 1b40d5f0,   客户@ ea4a92b,员工@ 3c5a99da,患者@ 47f37ef1,   Patient @ 5a01ccaa,Student @ 71c7db30]

谢谢,任何建议都是最欢迎的。