簡體   English   中英

java比較器,如何按整數排序?

[英]java comparator, how to sort by integer?

我試圖在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() + ", ");
}
}

簡單地改變

public int compare(Dog d, Dog d1) {
  return d.age - d1.age;
}

public int compare(Dog d, Dog d1) {
  return d1.age - d.age;
}

如果你正在尋找的話,應該按照年齡的相反順序對它們進行排序。

更新:

@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);
    }

}

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

// Sorts the array list using comparator
Collections.sort(list, Dog.DESCENDING_COMPARATOR);

在實現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();

Collections.sort的語法保持不變,但compare可以寫為

public int compare(Dog d, Dog d1) {
    return DESCENDING_COMPARATOR.compare(d, d1);
}

只需更換:

return d.age - d1.age;

通過:

return ((Integer)d.age).compareTo(d1.age);

或反轉以反轉列表:

return ((Integer)d1.age).compareTo(d.age);

編輯:

修正了“記憶問題”。
實際上,更好的解決方案是將Dog類中的age字段更改為Integer ,因為有許多好處,例如null可能性......

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

從Java 8開始,您可以使用:

Comparator.comparingInt(Dog::getDogAge).reversed();

一個簡單的方法是

Comparator<Dog> ageAscendingComp = ...;
Comparator<Dog> ageDescendingComp = Collections.reverseOrder(ageAscendingComp);
// then call the sort method

另外,Dog應該不會實現Comparator 這意味着你必須做一些奇怪的事情

Collections.sort(myList, new Dog("Rex", 4));
// ^-- why is a new dog being made? What are we even sorting by?!
Collections.sort(myList, myList.get(0));
// ^-- or perhaps more confusingly

相反,您應該將Compartors作為單獨的類。

例如。

public class DogAgeComparator implments Comparator<Dog> {
    public int compareTo(Dog d1, Dog d2) {
        return d1.getAge() - d2.getAge();
    }
}

這樣做的另一個好處是,您可以使用類的名稱來說明比較器如何對列表進行排序。 例如。

Collections.sort(someDogs, new DogNameComparator());
// now in name ascending order

Collections.sort(someDogs, Collections.reverseOrder(new DogAgeComparator()));
// now in age descending order

你也應該沒有Dog實現Comparable Comparable接口用於表示有一些固有的和自然的方式來訂購這些對象(例如數字和字符串)。 現在這不是Dog對象的情況,因為有時您可能希望按年齡排序,有時您可能希望按名稱排序。

如果您可以訪問Java 8 Comparable API,則可以使用Comparable.comparingToInt() (參見Java 8 Comparable Documentation )。

例如,可以使用以下命令創建Comparator<Dog>以按年齡降序排序Dog實例:

Comparable.comparingToInt(Dog::getDogAge).reversed();

該函數將lambda映射TInteger ,並創建一個升序比較器。 鏈接函數.reversed()將升序比較器轉換為降序比較器。

注意:雖然這可能對大多數Android版本沒有用,但我在搜索非Android Java應用程序的類似信息時遇到了這個問題。 我認為在同一地點的其他人看看我最終解決的問題可能會有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM