2013-09-21 2 views
-1

Сценария У меня есть BRAND_NAME, model_no и цена мобильной компании, и я должен отсортировать его по BRAND_NAME мобильных. И я использую Collections.sort для естественной сортировки и сравнения для пользовательской сортировки, но из-за некоторой проблемы этот код не компилируется. Пожалуйста, любой может помочь мне решить эту проблемуСортировка Arraylist с помощью Collections.sort и comparetor

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) 
+1

Если он не компилируется, отправьте сообщение об ошибке компилятора. Если компилируется, но вы получаете исключение приложения, то отправляйте стек. Если проблема в том, что она не сортируется так, как ожидалось, используйте отладчик. –

+3

Вы не должны использовать raw type для arraylist 'Phones'. Кстати, следуйте соглашению по именованию Java ... это 'phones'not' Phones' – Julien

+0

ohh ok thanks ... – Som

ответ

1

Проблема, что SmartPhone класс реализует Comparable , но метод compareTo принимает аргумент типа SmartPhone, а compareTo объявлен как t на Object. Вы можете решить эту проблему путем изменения compareTo в SmartPhone к следующему:

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

Этот код работает, потому что этот метод не будет вызываться с аргументом типа, кроме SmartPhone, если вы сделаете ошибку, и поставить что-то другое, чем SmartPhone в списке массивов.


Вы можете избежать всех этих проблем с помощью generics. С дженериков ваш код становится это:

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 Tutorial for Generics.

+0

Большое спасибо ... – Som

+0

Добро пожаловать. – tbodt

1

Вы должны заменить 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<>();

+0

Благодарим за помощь .... – Som

2

Сопоставимые и компараторы являются общими интерфейсами, вы должны реализовать их, поставив «реализует Comparable < T>», а T - класс, который вы вводите методом compareTo. Поскольку вы не указали T, он воспринимает это как объект, поэтому, помещая SmartPhone в качестве аргумента в compareTo, вы фактически не используете метод, который вы использовали для использования, используя Comparable. В вашем коде, если вы поместите Comparable < SmartPhone> и Comparator < SmartPhone>, тогда ваш код должен скомпилироваться.

+0

Благодарим за помощь .... – Som

Смежные вопросы