簡體   English   中英

使用Collections.sort和比較器對Arraylist進行排序

[英]Sorting of Arraylist using Collections.sort and comparetor

場景是我有移動公司的brand_name,model_no和價格 ,我必須根據移動公司的brand_name對其進行排序。 我正在使用Collections.sort進行自然排序,並使用比較器進行自定義排序,但是由於某些問題,此代碼無法編譯。 請任何人可以幫助我解決此問題

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ArrayListSortingExample {
   private static class SmartPhone implements Comparable {
    private String brand;
    private String model;
    private int price;
    public SmartPhone(String brand, String model, int price){
        this.brand = brand;
        this.model = model;
        this.price = price;
    }
    @Override
    public int compareTo(SmartPhone sp) {
        return this.brand.compareTo(sp.brand);
    }
    @Override
    public String toString() {
        return "SmartPhone{" + "brand=" + brand + ", model=" + model + ", price=" + price + '}';
    }
}
private static class PriceComparator implements Comparator{
    @Override
    public int compare(SmartPhone sp1, SmartPhone sp2) {
        return (sp1.price < sp2.price ) ? -1: (sp1.price > sp2.price) ? 1:0 ;
    }
}
public static void main(String... args) {
    SmartPhone apple = new SmartPhone("Apple", "IPhone4S",1000);
    SmartPhone nokia = new SmartPhone("Nokia", "Lumia 800",600);
    SmartPhone samsung = new SmartPhone("Samsung", "Galaxy Ace",800);
    SmartPhone lg = new SmartPhone("LG", "Optimus",500);
    ArrayList Phones = new ArrayList();
    Phones.add(apple);
    Phones.add(nokia);
    Phones.add(samsung);
    Phones.add(lg);
    Collections.sort(Phones);
    System.out.println(Phones);
    Collections.sort(Phones, new PriceComparator());
    System.out.println(Phones);
}
}

輸出應如下所示:

[SmartPhone{brand=Apple, model=IPhone4S, price=1000}, SmartPhone{brand=LG, model=Optimus, price=500}, SmartPhone{brand=Nokia, model=Lumia 800, price=600}, SmartPhone{brand=Samsung, model=Galaxy Ace, price=800}]

[SmartPhone{brand=LG, model=Optimus, price=500}, SmartPhone{brand=Nokia, model=Lumia 800, price=600}, SmartPhone{brand=Samsung, model=Galaxy Ace, price=800}, SmartPhone{brand=Apple, model=IPhone4S, price=1000}]

錯誤是

Exception in thread "main" java.lang.AbstractMethodError: employee.ArrayListSortingExample$SmartPhone.compareTo(Ljava/lang/Object;)I
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
at employee.ArrayListSortingExample.main(ArrayListSortingExample.java:37)

Comparable和Comparator都是通用接口,您應該通過放置“ implements Comparable <T>”來實現它們,其中T是您在compareTo方法中放置的類。 由於您尚未指定T,因此會將其視為Object,因此通過將SmartPhone用作compareTo中的參數,您實際上並沒有使用通過實現Comparable約定使用的方法。 如果在代碼中放置Comparable <SmartPhone>和Comparator <SmartPhone>,則您的代碼應進行編譯。

問題是SmartPhone類實現Comparable ,但是compareTo方法采用SmartPhone類型的參數,並且compareTo被聲明為采用Object 您可以通過將SmartPhonecompareTo更改為以下內容來解決此問題:

@Override
public int compareTo(Object o) {
    SmartPhone sp = (SmartPhone) o;
    return this.brand.compareTo(sp.brand);
}

該代碼之所以有效,是因為除非您犯了錯誤並將非SmartPhone放入數組列表,否則永遠不會使用SmartPhone類型的參數來調用此方法。


使用泛型可以避免所有這些問題。 使用泛型,您的代碼將變為:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ArrayListSortingExample {
   private static class SmartPhone implements Comparable<SmartPhone> {
    private String brand;
    private String model;
    private int price;
    public SmartPhone(String brand, String model, int price){
        this.brand = brand;
        this.model = model;
        this.price = price;
    }
    @Override
    public int compareTo(SmartPhone sp) {
        return this.brand.compareTo(sp.brand);
    }
    @Override
    public String toString() {
        return "SmartPhone{" + "brand=" + brand + ", model=" + model + ", price=" + price + '}';
    }
}
private static class PriceComparator implements Comparator<SmartPhone> {
    @Override
    public int compare(SmartPhone sp1, SmartPhone sp2) {
        return (sp1.price < sp2.price ) ? -1: (sp1.price > sp2.price) ? 1:0 ;
    }
}
public static void main(String... args) {
    SmartPhone apple = new SmartPhone("Apple", "IPhone4S",1000);
    SmartPhone nokia = new SmartPhone("Nokia", "Lumia 800",600);
    SmartPhone samsung = new SmartPhone("Samsung", "Galaxy Ace",800);
    SmartPhone lg = new SmartPhone("LG", "Optimus",500);
    ArrayList<SmartPhone> Phones = new ArrayList<SmartPhone>();
    Phones.add(apple);
    Phones.add(nokia);
    Phones.add(samsung);
    Phones.add(lg);
    Collections.sort(Phones);
    System.out.println(Phones);
    Collections.sort(Phones, new PriceComparator());
    System.out.println(Phones);
}
}

有關泛型的完整說明,請參見《 泛型Java教程》

您應該將implements Comparable替換為Comparable<SmartPhone> ,並將implements Comparator替換為Comparator<SmartPhone> 比較器和可比較接口使用泛型。 因此,您需要指定要比較的類型。

而且ArrayList Phones = new ArrayList(); 不好,因為您使用的是原始類型和錯誤的名稱(大寫表示類)。 替換為ArrayList<SmartPhone> phones = new ArrayList<SmartPhone>(); 泛型非常有用,可以防止您在運行時強制拋出異常。 如果您使用的是JAVA SE 7,請使用菱形運算符ArrayList<SmartPhone> phones = new ArrayList<>();

暫無
暫無

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

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