【问题标题】:Sorting Object of ArrayList with combination of different Attributes [closed]使用不同属性的组合对 ArrayList 的对象进行排序[关闭]
【发布时间】:2012-11-13 15:35:23
【问题描述】:

我的课是这样的:

class Employee{
  int age;
  String name;
  int empId;
  .
  .
  . 
 }

在 main 方法中,我创建了 Employee 类的对象并将其保存在 ArrayList 中,比如 objEmpList。 现在,我的要求是像 SQL 语句一样对 objEmpList 进行排序, Select * From Employee Order by age,name,empId; Measn,我想要按年龄、姓名和 empId 排序的结果。

例如: 我的数据是这样的: 10 尼德什 1 10 安贝什 222 9 拉梅什 9 12 阿马尔 3

所以我的结果应该是,

 9    Ramesh  9
 10   Ambesh  222
 10   Ramesh  1 
 12   Amar    3

我怎样才能达到这个要求?

【问题讨论】:

  • 除了上面的评论 - 你有没有做过任何研究?任何谷歌搜索?
  • 我尝试将所有属性的结果与每个 hashcode() 相加,并与具有可比接口的其他属性相减。但这不起作用。
  • 是的,我厌倦了谷歌,但找不到解决方案。
  • 您应该使用 Comparable 接口和属性并实现自己的算法
  • @Nirdesh,请在下面查看我的答案。你应该可以接受!

标签: java collections arraylist comparator comparable


【解决方案1】:

让 Employee 实现 Comparable,然后调用 Collections.sort(list);

public class Employee implements Comparable<Employee> {

    // rest of class omitted

    public int compareTo(Employee e) {
       // Here's how you order by age, name, empId
       if (age != e.age) return age - e.age;
       if (!name.equal(e.name) return name.compareTo(e.name);
       return empId - e.empId;
    }
}

然后

Collections.sort(list);

【讨论】:

  • 但是在 compareTo() 方法中,我如何根据这 3 个属性进行排序。
  • 负整数、零或正整数,因为此对象小于、等于或大于指定对象。
  • 我对如何实现排序代码感到困惑。你能写一个实现上述顺序的代码
  • @Nirdesh:尝试自己搜索互联网。不要指望用勺子喂食总是好的。请以积极的态度对待这个
  • @Nirdesh:检查我关于使用反射的回答。这是从哪里开始搜索的提示。
【解决方案2】:

您应该实现一个实现 Comparator 的新类 EmployeeComparator。通过指定字段名称的可变参数列表public EmployeeComparator(String... fields) 来配置字段顺序。

这是一个例子:

public class CarComparator implements Comparator<Car> {

private final List<String> fieldSortOrder;

public CarComparator(String... fieldSortOrder) {
    this.fieldSortOrder = new ArrayList<String>(
            Arrays.asList(fieldSortOrder));
}

@Override
public int compare(Car a, Car b) {
    try {
        return cmp(a, b, fieldSortOrder);
    } catch (Exception e) {
        return 0;
    }
}

private int cmp(Car a, Car b, final List<String> fields) throws Exception {
    if (fields.isEmpty())
        return 0;

    PropertyDescriptor pd = new PropertyDescriptor(fields.get(0), Car.class);
    String ma = (String) pd.getReadMethod().invoke(a);
    String mb = (String) pd.getReadMethod().invoke(b);
    if (ma.compareTo(mb) == 0) {
        return cmp(a, b, fields.subList(1, fields.size()));
    } else {
        return ma.compareTo(mb);
    }
}

}

然后将列表排序如下:

Collection.sort(cars, new CarComparator("brand", "mileage"));

对于值对象中的每个字段,您都需要访问器(即 getter 和 setter),而上面的示例对于非字符串字段会有些麻烦。但我想我应该把一些乐趣留给你! :)

祝你好运!

【讨论】:

  • +1 正确应用 DRY 原则(不要重复自己)
【解决方案3】:

-如果要根据对象的多个属性进行排序,可以使用java.util.Compartor&lt;T&gt;接口。

-您必须使用Collections.sort(List&lt;?&gt; l, Comparator c)。

例如:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

class Car {

    private String name;
    private String brand;
    private double cost;

    public Car(String name, String brand, double cost) {

        this.name = name;
        this.brand = brand;
        this.cost = cost;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getCost() {
        return cost;
    }

    public void setCost(double cost) {
        this.cost = cost;
    }

    public String toString() {

        return getName();
    }

}

public class Hog {

    ArrayList<Car> cars = new ArrayList<Car>();

    public void setIt() {

        cars.add(new Car("Padmini", "Fiat", 100008.00));
        cars.add(new Car("XYlo", "Mahindra", 100000.00));
        cars.add(new Car("Swift", "Maruti", 200000.00));
    }

    public void sortIt() {

        Collections.sort(cars, new NameComparator());
        System.out.println(cars);
        Collections.sort(cars, new BrandComparator());
        System.out.println(cars);
        Collections.sort(cars, new CostComparator());
        System.out.println(cars);
    }

    class NameComparator implements Comparator<Car> {

        public int compare(Car c1, Car c2) {

            return c1.getName().compareTo(c2.getName());
        }
    }

    class BrandComparator implements Comparator<Car> {

        public int compare(Car c1, Car c2) {

            return c1.getBrand().compareTo(c2.getBrand());
        }
    }

    class CostComparator implements Comparator<Car> {

        public int compare(Car c1, Car c2) {

            return new Double(c1.getCost()).compareTo(new Double(c2.getCost()));
        }
    }

    public static void main(String[] args) {

        Hog h = new Hog();

        h.setIt();
        h.sortIt();
    }

}

【讨论】:

  • 如果有很多字段,这可能会导致很多比较器。另外,如果您想按品牌订购,然后按成本订购,那您就有麻烦了,对吧?
  • @Markus,嗯,直到现在才感受到这种热度……我一直在一个项目中,它以 8 种不同的方式处理对象的排序……嗯,编程风格很有争议,我更喜欢这种方式,因为到目前为止我已经使用它完美地航行了......如果你能为我提供更好的解决方案,那将是一种荣幸和相当的学习经验,我将非常感谢你...
  • 检查我更新的答案。
猜你喜欢
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-25
  • 2023-03-28
相关资源
最近更新 更多