java比较器,如何按整数排序?

Edm*_*jas 35 java android sql-order-by comparator

我试图在java中学习比较器,我在网上找到了这个很好的例子,我的问题是如何更改这些代码,以便按年龄和降序排列宠物名称,以便最老的是第一个,最小的是最后一个?

class Dog implements Comparator<Dog>, Comparable<Dog>{
private String name;
private int age;
Dog(){
}

Dog(String n, int a){
  name = n;
  age = a;
}

public String getDogName(){
  return name;
}

public int getDogAge(){
  return age;
}

// Overriding the compareTo method
public int compareTo(Dog d){
  return (this.name).compareTo(d.name);
}

// Overriding the compare method to sort the age 
public int compare(Dog d, Dog d1){
  return d.age - d1.age;
}
}

public class Example{
public static void main(String args[]){
  // Takes a list o Dog objects
  List<Dog> list = new ArrayList<Dog>();

  list.add(new Dog("Shaggy",3));
  list.add(new Dog("Lacy",2));
  list.add(new Dog("Roger",10));
  list.add(new Dog("Tommy",4));
  list.add(new Dog("Tammy",1));
  Collections.sort(list);// Sorts the array list

  for(Dog a: list)//printing the sorted list of names
     System.out.print(a.getDogName() + ", ");

  // Sorts the array list using comparator
  Collections.sort(list, new Dog());
  System.out.println(" ");
  for(Dog a: list)//printing the sorted list of ages
     System.out.print(a.getDogName() +"  : "+
     a.getDogAge() + ", ");
}
}
Run Code Online (Sandbox Code Playgroud)

Jes*_*run 91

简单地改变

public int compare(Dog d, Dog d1) {
  return d.age - d1.age;
}
Run Code Online (Sandbox Code Playgroud)

public int compare(Dog d, Dog d1) {
  return d1.age - d.age;
}
Run Code Online (Sandbox Code Playgroud)

如果你正在寻找的话,应该按照年龄的相反顺序对它们进行排序.

更新:

@Arian在他的评论中是正确的,为狗声明一个比较器的公认方法之一是你将它声明为类本身的公共静态最终字段.

class Dog implements Comparable<Dog> {
    private String name;
    private int age;

    public static final Comparator<Dog> DESCENDING_COMPARATOR = new Comparator<Dog>() {
        // Overriding the compare method to sort the age
        public int compare(Dog d, Dog d1) {
            return d.age - d1.age;
        }
    };

    Dog(String n, int a) {
        name = n;
        age = a;
    }

    public String getDogName() {
        return name;
    }

    public int getDogAge() {
        return age;
    }

    // Overriding the compareTo method
    public int compareTo(Dog d) {
        return (this.name).compareTo(d.name);
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在代码中的任何位置使用它,如下所示:

// Sorts the array list using comparator
Collections.sort(list, Dog.DESCENDING_COMPARATOR);
Run Code Online (Sandbox Code Playgroud)

在实现Comparable时要记住的另一个重要事项是compareTo与equals一致执行非常重要.尽管不是必需的,但如果不这样做可能会导致某些集合出现奇怪的行为,例如集合的某些实现.有关实施compareTo的合理原则的更多信息,请参阅文章.

更新2: 克里斯是对的,这个代码很容易因年龄大的负值而溢出.在Java 7及更高版本中实现此功能的正确方法将是Integer.compare(d.age, d1.age)代替d.age - d1.age.

更新3: 使用Java 8,您的比较器可以更简洁地编写为:

public static final Comparator<Dog> DESCENDING_COMPARATOR = 
    Comparator.comparing(Dog::getDogAge).reversed();
Run Code Online (Sandbox Code Playgroud)

Collections.sort保持相同的语法,但compare可以写为

public int compare(Dog d, Dog d1) {
    return DESCENDING_COMPARATOR.compare(d, d1);
}
Run Code Online (Sandbox Code Playgroud)

  • 这里不太可能代表一个问题,但是这个比较器中有一个整数溢出/下溢错误.如果狗的年龄为"Integer.MIN_VALUE"和任何正整数(或"Integer.MAX_VALUE"和任何负数),您将获得环绕并且排序顺序将是意外的.这看起来很愚蠢,但这是我认为程序员应该考虑的事情,即使比较狗的年龄.尝试使用`Integer.compare`(以及其他`java.lang.Number`子类中的其他类似方法),而不是执行自己的减法. (4认同)

eli*_*ias 19

只需更换:

return d.age - d1.age;
Run Code Online (Sandbox Code Playgroud)

通过:

return ((Integer)d.age).compareTo(d1.age);
Run Code Online (Sandbox Code Playgroud)

或反转以反转列表:

return ((Integer)d1.age).compareTo(d.age);
Run Code Online (Sandbox Code Playgroud)

编辑:

修正了"记忆问题".
事实上,更好的解决方案是改变班级中的age领域,因为有很多好处,比如可能性......DogIntegernull

  • 为什么不简单地使用`return Integer.compare(d.age,d1.age);`?自Java 7起可用 (6认同)
  • 以不必要的方式创建对象为代价.当您要进行大量排序时,不要对大型数据集执行此操作.特别是,因为替代方案更简单...... (4认同)
  • android上的Integer.compare需要api> = 19 (3认同)

小智 19

public class DogAgeComparator implements Comparator<Dog> {
    public int compare(Dog o1, Dog o2) {
        return Integer.compare(o1.getAge(), o2.getId());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您能否详细说明您的答案,添加一些关于您提供的解决方案的更多描述? (4认同)
  • 由于Integer.compare(o1.getAge(),o2.getId()),此代码需要最低API级别19.如果要在较低的API级别使用它,可以使用o1.getAge() - o2.getAge()instade (4认同)
  • 我想你的意思是`Integer.compare(o1.getDogAge(),o2.getDogAge())`?OP的Dog类没有`getAge`,从年龄减去ID也没有意义. (3认同)

jot*_*ta3 9

从Java 8开始,您可以使用:

Comparator.comparingInt(Dog::getDogAge).reversed();
Run Code Online (Sandbox Code Playgroud)