使用不同的键排序列表

时间:2015-02-06 20:47:23

标签: java sorting object

极端新手在这里努力处理列表可能排序的所有不同方式。假设我有一个对象列表,每个对象都有几个可用于在不同情况下进行排序的键。我从这个帖子中得到了一些非常有用的信息: Java Interface Comparator static compare, 使用Qwerky的第一个例子作为模型创建:

class Dog {
   private String name;
   private int age;
   private int height;
   private int weight;

   Dog(String n, int a, int b, int c){
      name = n;
      age = a;
      height = b;
      weight = c;
   }
   public String getDogName(){
      return name;
   }
   public int getDogAge(){
      return age;
   } 
   public int getDogHeight(){
      return height;
   }
   public int getDogWeight(){
      return weight;
   }
}

class DogComparator1 implements Comparator<Dog> {
   @Override
   public int compare(Dog d, Dog d1){
      return d.getDogAge() - d1.getDogAge();
   }
}
   class DogComparator2 implements Comparator<Dog> {
   @Override
   public int compare(Dog d, Dog d1){
      return d.getDogHeight() - d1.getDogHeight();
   }
}
   class DogComparator3 implements Comparator<Dog> { 
   @Override
   public int compare(Dog d, Dog d1){
      return d.getDogWeight() - d1.getDogWeight();
   }
}


public class Example{

   public static void main(String args[]){
      // Creat list of dog objects
      List<Dog> dogList = new ArrayList<>();

      // Add a buch of dogs to the list here
               .
               .

      // Create the Comparators
      DogComparator1 compare1 = new DogComparator1();
      DogComparator2 compare2 = new DogComparator2();
      DogComparator3 compare3 = new DogComparator3();


      // Sort the list using Comparators
      Collections.sort(list, compare1);  // Sort by age     
      Collections.sort(list, compare2);  // Sort by height
      Collections.sort(list, compare3);  // Sort by weight          
   }
}

但是,这似乎并不正确。我想我想在Dog类中“拉”比较器定义,以便很好地封装它们。但是,无法弄清楚如何去做。

我是否在正确的轨道上?如果是这样,将非常感谢帮助正确的语法。

3 个答案:

答案 0 :(得分:5)

你肯定是在正确的轨道上。

我只想在Dog课程中添加:

public static final Comparator<Dog> COMPARE_BY_AGE = new Comparator<Dog>() {
    @Override
    public int compare(Dog d, Dog d1) {
        return d.getDogAge() - d1.getDogAge();
    }
};

public static final Comparator<Dog> COMPARE_BY_HEIGHT = new Comparator<Dog>() {
    @Override
    public int compare(Dog d, Dog d1) {
        return d.getDogHeight() - d1.getDogHeight();
    }
};

public static final Comparator<Dog> COMPARE_BY_WEIGHT = new Comparator<Dog>() {
    @Override
    public int compare(Dog d, Dog d1) {
        return d.getDogWeight() - d1.getDogWeight();
    }
};

然后用法如下:

    // Sort the list using Comparators
    Collections.sort(list, Dog.COMPARE_BY_AGE);  // Sort by age
    Collections.sort(list, Dog.COMPARE_BY_HEIGHT);  // Sort by height
    Collections.sort(list, Dog.COMPARE_BY_WEIGHT);  // Sort by weight

答案 1 :(得分:3)

我不认为Dog类有责任了解比较它的不同方法。但是,你可以创建那些比较器作为内部类,如果它会感觉更多&#34;封装&#34;为你(甚至使这个类私有)。

即。你可以在Dog课堂里这样做:

public class Dog {

(...)

    public Comparator<Dog> getAgeComparator() {
        return new AgeComparator();
    }

    private static class AgeComparator implements Comparator<Dog> {
       @Override
       public int compare(Dog d, Dog d1){
          return d.getDogAge() - d1.getDogAge();
       }
}

或者,不是创建getAgeComparator()方法而是将这些比较器公开为:

public static final Comparator<Dog> AGE_COMPARATOR = new AgeComparator();

您也可以在那里创建匿名实现。 你这样做的方式是正确的。我不会让狗意识到如何比较它。您可以轻松地将这些实现放在其他地方,或者如果不重用它们,甚至可以动态创建匿名类实现。你想要实现的是对封装的错误理解。

您可以通过Dog类实现Comparable<Dog>来创建默认比较器:

public class Dog implements Comparable<Dog> {

    public int compareTo(Dog dog) {
        return AGE_COMPARATOR.compare(this, dog); // or inline comparison here
    }

    (...)
}

答案 2 :(得分:1)

考虑使用Comparator#comparingInt创建比较器:

  list.sort(Comparator.comparingInt(Dog::getDogAge));  // Sort by age     
  list.sort(Comparator.comparingInt(Dog::getDogHeight));  // Sort by height
  list.sort(Comparator.comparingInt(Dog::getDogWeight));  // Sort by weight  

通过这种方式,您无需像现在一样编写自己的Comparator<Dog>实现,而且很容易确切地看到正在比较的内容。

由于Comparator已经只使用了Dog的公共方法而且它们很短,所以没有太多理由将它们封装在Dog中。