-1

シナリオは、モバイル会社の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)
4

3 に答える 3

2

Comparable と Comparator はどちらもジェネリック インターフェイスです。'implements Comparable < T >' を配置して実装する必要があります。T はメソッド compareTo に配置するクラスです。T を指定していないため、それを Object と見なしているため、compareTo の引数として SmartPhone を配置することで、Comparable を実装することで使用するように契約したメソッドを実際には使用していません。コードに Comparable< SmartPhone > と Comparator< SmartPhone > を配置すると、コードがコンパイルされます。

于 2013-09-21T17:26:14.257 に答える
1

問題は、SmartPhoneクラスが を実装しているのにComparablecompareToメソッドが 型の引数を取り、 を受け取るSmartPhonecompareTo宣言されていることObjectです。この問題は、compareToinSmartPhoneを次のように変更することで解決できます。

@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 Comparableあります。Comparator および Comparable インターフェイスはジェネリックを使用します。したがって、比較するタイプを指定する必要があります。Comparable<SmartPhone>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 に答える