-1

场景是我有手机公司的品牌名称、型号和价格,我必须根据手机的品牌名称对其进行排序。我使用 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)
4

3 回答 3

2

Comparable 和 Comparator 都是通用接口,你应该通过放置“implements Comparable < T >”来实现它们,其中 T 是你放在方法 compareTo 中的类。由于您没有指定 T,因此将其视为 Object,因此通过将 SmartPhone 作为参数放在 compareTo 中,您实际上并没有使用您通过实现 Comparable 约定使用的方法。在您的代码中,如果您放置 Comparable< SmartPhone > 和 Comparator< SmartPhone > 那么您的代码应该可以编译。

于 2013-09-21T17:26:14.257 回答
1

问题是SmartPhone该类实现了Comparable,但该compareTo方法采用类型的参数SmartPhone,并compareTo声明为采用Object. compareTo您可以通过将in更改SmartPhone为以下内容来解决此问题:

@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 泛型教程

于 2013-09-21T17:23:02.597 回答
1

您应该替换implements ComparableComparable<SmartPhone>和。Comparator 和 Comparable 接口使用泛型。因此,您需要指定要比较的类型。implements ComparatorComparator<SmartPhone>

而且ArrayList Phones = new ArrayList();不好,因为您使用的是原始类型和坏名称(大写用于类)。替换为ArrayList<SmartPhone> phones = new ArrayList<SmartPhone>();。泛型很有用,可以防止您在运行时强制转换异常。如果您使用的是 JAVA SE 7,请使用菱形运算符ArrayList<SmartPhone> phones = new ArrayList<>();

于 2013-09-21T17:24:11.950 回答