Java对不同类型对象的列表进行排序

时间:2019-08-09 18:49:52

标签: java sorting

我有几个从类Z扩展的类A,B和C。类Z具有属性private Date dateCreated = new Date();

我正在使用以下方法收集列表中的数据:

List<A> aList = repo.listA();
List<B> aList = repo.listB();
List<C> aList = repo.listC();

,然后使用

组合列表
List<Object> combinedList = new ArrayList<Object>
combinedList.addAll(aList);
combinedList.addAll(bList);
combinedList.addAll(cList);

现在,我想按来自类Z的属性dateCreated对对象列表进行排序。我试图像这样使用比较器:

Collections.sort(combinedList, new Comparator<Object>() {
    @Override
    public int compare(Object o1, Object o2) {
        return o1.getDateModified().compareTo(o2.getDateModified());
    }
});

但是这不起作用,因为未为对象定义getDateModified()。 我还尝试过向Z类添加方法,如下所示:

  @Override
  public int compareTo(Z o) {
    return getDateModified().compareTo(o.getDateModified());
  }

但是当我尝试使用 Collections.sort(combinedList)我收到以下错误:

The method sort(List<T>) in the type Collections is not applicable for the arguments (List<Object>)

我应该如何对CombinedList进行排序?

2 个答案:

答案 0 :(得分:2)

您需要将列表定义为Z类型而不是Object,然后才能使用Comparator<Z>

List<Z> combinedList = new ArrayList<>();
combinedList.addAll(aList);
combinedList.addAll(bList);
combinedList.addAll(cList);

答案 1 :(得分:0)

我不确定您是否被迫使用列表列表,但是我不喜欢使用这样的列表(只要没有必要)。除了只具有一个列表之外,您还可以只具有一个List<Z>并让Z类实现Comparable接口,以便对扩展Z的类的对象进行排序。然后,为了从A类(A extends Z)获得所有对象的排序列表,只需: List<A> sortedA = zList.stream().filter(A.class::isInstance).map(A.class::cast).sorted().collect(Collectors.toList());

如果您甚至允许父类实现Comparable,则可以获得按公共属性排序的Z对象的排序版本。

完整示例:

public class Lists {
    private static class Employee implements Comparable<Employee> {
        protected int salary;

        // All employees sortable by salary
        @Override
        public int compareTo(Employee o) {
            return salary - o.salary;
        }

    }

    private static class HourlyEmployee extends Employee {
        private int hoursWorked;

        public HourlyEmployee(int hoursWorked) {
            this.hoursWorked = hoursWorked;
            this.salary = hoursWorked * 12; // use setter instead or parent constructor
        }

        // Sort hourly employees by hours worked.
        @Override
        public int compareTo(Employee o) {
            if (o instanceof HourlyEmployee) {
                HourlyEmployee hourlyEmployee = (HourlyEmployee) o;
                // Getter should be used here
                return hoursWorked - hourlyEmployee.hoursWorked;
            }
            return super.compareTo(o);
        }

        @Override
        public String toString() {
            return "HourlyEmployee [hoursWorked=" + hoursWorked + ", salary=" + salary + "]";
        }

    }

    private static class MonthlyEmployee extends Employee {
        private int monthsWorked;

        public MonthlyEmployee(int monthsWorked) {
            this.monthsWorked = monthsWorked;
            this.salary = monthsWorked * 100; // again use setter instead
        }

        // Sort montly employees by months worked.
        @Override
        public int compareTo(Employee o) {
            if (o instanceof MonthlyEmployee) {
                MonthlyEmployee monthlyEmployee = (MonthlyEmployee) o;
                // Getter should be used here
                return monthsWorked - monthlyEmployee.monthsWorked;
            }
            return super.compareTo(o);
        }

        @Override
        public String toString() {
            return "MonthlyEmployee [monthsWorked=" + monthsWorked + ", salary=" + salary + "]";
        }
    }

    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();
        employees.add(new HourlyEmployee(5));
        employees.add(new HourlyEmployee(55));
        employees.add(new HourlyEmployee(12));
        employees.add(new HourlyEmployee(15));
        employees.add(new HourlyEmployee(4));

        employees.add(new MonthlyEmployee(51));
        employees.add(new MonthlyEmployee(44));
        employees.add(new MonthlyEmployee(72));
        employees.add(new MonthlyEmployee(12));
        employees.add(new MonthlyEmployee(4));
        System.out.println("Sorted hourly employess:");
        List<HourlyEmployee> sortedHourlyEmployees = employees.stream().filter(HourlyEmployee.class::isInstance).map(HourlyEmployee.class::cast).sorted()
                .collect(Collectors.toList());
        sortedHourlyEmployees.forEach(System.out::println);

        System.out.println();
        System.out.println("Sorted monthly employess:");

        List<MonthlyEmployee> sortedMonthlyEmployees = employees.stream().filter(MonthlyEmployee.class::isInstance).map(MonthlyEmployee.class::cast).sorted()
                .collect(Collectors.toList());
        sortedMonthlyEmployees.forEach(System.out::println);

        System.out.println();
        System.out.println("Sorted employess:");

        List<Employee> sortedEmployeesBySalary = employees.stream().sorted().collect(Collectors.toList());
        sortedEmployeesBySalary.forEach(System.out::println);
    }
}

哪个输出:

Sorted hourly employess:
HourlyEmployee [hoursWorked=4, salary=48]
HourlyEmployee [hoursWorked=5, salary=60]
HourlyEmployee [hoursWorked=12, salary=144]
HourlyEmployee [hoursWorked=15, salary=180]
HourlyEmployee [hoursWorked=55, salary=660]

Sorted monthly employess:
MonthlyEmployee [monthsWorked=4, salary=400]
MonthlyEmployee [monthsWorked=12, salary=1200]
MonthlyEmployee [monthsWorked=44, salary=4400]
MonthlyEmployee [monthsWorked=51, salary=5100]
MonthlyEmployee [monthsWorked=72, salary=7200]

Sorted employess:
HourlyEmployee [hoursWorked=4, salary=48]
HourlyEmployee [hoursWorked=5, salary=60]
HourlyEmployee [hoursWorked=12, salary=144]
HourlyEmployee [hoursWorked=15, salary=180]
MonthlyEmployee [monthsWorked=4, salary=400]
HourlyEmployee [hoursWorked=55, salary=660]
MonthlyEmployee [monthsWorked=12, salary=1200]
MonthlyEmployee [monthsWorked=44, salary=4400]
MonthlyEmployee [monthsWorked=51, salary=5100]
MonthlyEmployee [monthsWorked=72, salary=7200]

其中MonthlyEmployeeHourlyEmployee代表AB。雇员代表父类Z。 也不要忽略有关getter和setter的评论。出于示例目的,我没有使用它们:)