2012-02-02 10 views
67

Próbuję sortować listę obiektów według określonej wartości w obiekcie. Jakie byłoby najlepsze podejście do zrobienia czegoś takiego. Czy powinienem używać Collections.sort() z jakimś komparatorem?Android-java- Jak sortować listę obiektów według pewnej wartości w obiekcie

Próbuję posortować listę obiektów według wartości zmiennoprzecinkowej, jaką przechowują w jednej ze zmiennych.

EDIT: To, co mam tak daleko:

public class CustomComparator implements Comparator<Marker> { 
    @Override 
    public int compare(Mark o1, Mark o2) { 
     return o1.getDistance().compareTo(o2.getDistance()); 
    } 
} 

stany błędzie: Nie można powoływać compareTo (podwójne) na prymitywne typu podwójnego.

Czy to dlatego, że komparator nie może zwrócić niczego innego niż określony typ?

+2

„Czy mogę używać Collections.sort() z jakiegoś komparatora? "Tak, brzmi jak dobry pomysł. – Kennet

+0

Nie wiem, czy to ma znaczenie, ale liczba obiektów na liście będzie wynosiła nawet 80. Dlatego jestem w pewien sposób zdezorientowany, jeśli chodzi o używanie komparatora, jeśli to jest droga, ponieważ to tylko porównuje dwie wartości naraz: –

+0

Tak działa sortowanie Najpierw dodaj jeden element do listy Dodając następny, czy powinien on iść przed czy po bieżącym na liście Kiedy dodajesz trzeci element porównujesz do pierwszego elementu na liście, jeśli po tym czasie porównaj do następnego elementu itd. – Kennet

Odpowiedz

78

Powinieneś użyć Porównywalne zamiast Komparatora, jeśli szukany jest domyślny sort.

Zobacz tutaj, może to być pomocne - When should a class be Comparable and/or Comparator?

Spróbuj tego -

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

public class TestSort { 

    public static void main(String args[]){ 

     ToSort toSort1 = new ToSort(new Float(3), "3"); 
     ToSort toSort2 = new ToSort(new Float(6), "6"); 
     ToSort toSort3 = new ToSort(new Float(9), "9"); 
     ToSort toSort4 = new ToSort(new Float(1), "1"); 
     ToSort toSort5 = new ToSort(new Float(5), "5"); 
     ToSort toSort6 = new ToSort(new Float(0), "0"); 
     ToSort toSort7 = new ToSort(new Float(3), "3"); 
     ToSort toSort8 = new ToSort(new Float(-3), "-3"); 

     List<ToSort> sortList = new ArrayList<ToSort>(); 
     sortList.add(toSort1); 
     sortList.add(toSort2); 
     sortList.add(toSort3); 
     sortList.add(toSort4); 
     sortList.add(toSort5); 
     sortList.add(toSort6); 
     sortList.add(toSort7); 
     sortList.add(toSort8); 

     Collections.sort(sortList); 

     for(ToSort toSort : sortList){ 
      System.out.println(toSort.toString()); 
     } 
    } 

} 

public class ToSort implements Comparable<ToSort> { 

    private Float val; 
    private String id; 

    public ToSort(Float val, String id){ 
     this.val = val; 
     this.id = id; 
    } 

    @Override 
    public int compareTo(ToSort f) { 

     if (val.floatValue() > f.val.floatValue()) { 
      return 1; 
     } 
     else if (val.floatValue() < f.val.floatValue()) { 
      return -1; 
     } 
     else { 
      return 0; 
     } 

    } 

    @Override 
    public String toString(){ 
     return this.id; 
    } 
} 
+0

Hej, dzięki za link :) Wracam z jednego języka do następnego, więc zawsze coś mi brakuje: p wiesz jak to idzie ...... wszystkie zawody ale mistrz nie ma lol –

2

"Android-java" nie różni się tutaj od "normalnej javy", więc tak Collections.sort() byłoby dobrym podejściem.

+0

Ale jak mogę go sortować według wartości w obiekcie.To co mam utknąć na. –

1

Zróbmy Comparator, który może porównać twoje obiekty, lub jeśli wszystkie są instancjami tej samej klasy, możesz uczynić tę klasę implementującą Comparable. Następnie możesz użyć Collections.sort(), aby wykonać faktyczne sortowanie.

+0

Poszedłem i zaimplementowałem Porównywalne w mojej klasie, ale i stworzyłem metodę wywołania sortowania na list, gdy trzeba go posortować, ale jak sortować według wartości w obiekcie? –

+0

Metoda 'compareTo()' jest tam, gdzie dokonujesz porównania.Niektóre googling dał kilka szczegółowych przykładów, jak używać to jest jeden z nich: http://www.javadeveloper.co.in/java-example/java-comparable-example.html – Jave

+0

Ustawiłem metodę podobną do przykładu, ale pojawia się błąd stwierdzający, że nie mogę użyć compareTo na podwójnej obsadzie. Wydaje się, że z tego, co kiedykolwiek rozum, co robię to nie lubi. Nie można wywołać metody compareTo (double) na typie pierwotnym double. Dodam mój kod wyżej, żeby pokazać, co mam na myśli. –

36

Myślę, że to pomoże Ci lepiej

Person p = new Person("Bruce", "Willis"); 
Person p1 = new Person("Tom", "Hanks"); 
Person p2 = new Person("Nicolas", "Cage"); 
Person p3 = new Person("John", "Travolta"); 

ArrayList<Person> list = new ArrayList<Person>(); 
list.add(p); 
list.add(p1); 
list.add(p2); 
list.add(p3); 

Collections.sort(list, new Comparator() { 
    @Override 
    public int compare(Object o1, Object o2) { 
     Person p1 = (Person) o1; 
     Person p2 = (Person) o2; 
     return p1.getFirstName().compareToIgnoreCase(p2.getFirstName()); 
    } 
}); 
224

Śledź ten kod do sortowania żadnych ArrayList

Collections.sort(myList, new Comparator<EmployeeClass>(){ 
    public int compare(EmployeeClass obj1, EmployeeClass obj2) { 
     // ## Ascending order 
     return obj1.firstName.compareToIgnoreCase(obj2.firstName); // To compare string values 
     // return Integer.valueOf(obj1.empId).compareTo(obj2.empId); // To compare integer values 

     // ## Descending order 
     // return obj2.firstName.compareToIgnoreCase(obj1.firstName); // To compare string values 
     // return Integer.valueOf(obj2.empId).compareTo(obj1.empId); // To compare integer values 
     } 
    }); 
+4

To powinna być najlepsza odpowiedź! –

+1

prosta i świetna odpowiedź, kudos bro :) – Sadashiv

+0

Ten przykład działa w celu porównania ciągów. Do sortowania przez porównanie liczb całkowitych spójrz na odpowiedź Pranava poniżej. – Ambran

2
public class DateComparator implements Comparator<Marker> { 
    @Override 
    public int compare(Mark lhs, Mark rhs) { 
     Double distance = Double.valueOf(lhs.getDistance()); 
     Double distance1 = Double.valueOf(rhs.getDistance()); 
     if (distance.compareTo(distance1) < 0) { 
      return -1; 
     } else if (distance.compareTo(distance1) > 0) { 
      return 1; 
     } else { 
      return 0; 
     } 
    } 
} 

ArrayList(Marker) arraylist; 

Jak używać:

Collections.sort(arraylist, new DateComparator()); 
0

Mam ListView, który pokazuje informacje o wszystkich klientach ja sortujących klienci nazwę za pomocą tej niestandardowej klasy porównawczej. Oni mają jakiś dodatkowy lerret oprócz liter angielskich który zarządzam z tym setStrength (Collator.SECONDARY)

public class CustomNameComparator implements Comparator<ClientInfo> { 
     @Override 

    public int compare(ClientInfo o1, ClientInfo o2) { 

     Locale locale=Locale.getDefault(); 
     Collator collator = Collator.getInstance(locale); 
     collator.setStrength(Collator.SECONDARY); 
     return collator.compare(o1.title, o2.title); 

    } 
} 


PRIMARY strength: Typically, this is used to denote differences between base characters (for example, "a" < "b"). It is the strongest difference. For example, dictionaries are divided into different sections by base character. 
SECONDARY strength: Accents in the characters are considered secondary differences (for example, "as" < "às" < "at"). Other differences between letters can also be considered secondary differences, depending on the language. A secondary difference is ignored when there is a primary difference anywhere in the strings. 
TERTIARY strength: Upper and lower case differences in characters are distinguished at tertiary strength (for example, "ao" < "Ao" < "aò"). In addition, a variant of a letter differs from the base form on the tertiary strength (such as "A" and "Ⓐ"). Another example is the difference between large and small Kana. A tertiary difference is ignored when there is a primary or secondary difference anywhere in the strings. 
IDENTICAL strength: When all other strengths are equal, the IDENTICAL strength is used as a tiebreaker. The Unicode code point values of the NFD form of each string are compared, just in case there is no difference. For example, Hebrew cantellation marks are only distinguished at this strength. This strength should be used sparingly, as only code point value differences between two strings are an extremely rare occurrence. Using this strength substantially decreases the performance for both comparison and collation key generation APIs. This strength also increases the size of the collation key. 

**Here is a another way to make a rule base sorting if u need it just sharing** 

/*  String rules="< å,Å< ä,Ä< a,A< b,B< c,C< d,D< é< e,E< f,F< g,G< h,H< ï< i,I"+"< j,J< k,K< l,L< m,M< n,N< ö,Ö< o,O< p,P< q,Q< r,R"+"< s,S< t,T< ü< u,U< v,V< w,W< x,X< y,Y< z,Z"; 
     RuleBasedCollator rbc = null; 
     try { 
      rbc = new RuleBasedCollator(rules); 
     } catch (ParseException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     String myTitles[]={o1.title,o2.title}; 
     Collections.sort(Arrays.asList(myTitles), rbc);*/ 
2

Można porównać dwa String przy użyciu tego produktu.

Collections.sort(contactsList, new Comparator<ContactsData>() { 

        @Override 
        public int compare(ContactsData lhs, ContactsData rhs) { 

         char l = Character.toUpperCase(lhs.name.charAt(0)); 

         if (l < 'A' || l > 'Z') 

          l += 'Z'; 

         char r = Character.toUpperCase(rhs.name.charAt(0)); 

         if (r < 'A' || r > 'Z') 

          r += 'Z'; 

         String s1 = l + lhs.name.substring(1); 

         String s2 = r + rhs.name.substring(1); 

         return s1.compareTo(s2); 

        } 

       }); 

I teraz należy utworzyć klasę ContactData.

public class ContactsData { 

public String name; 
public String id; 
public String email; 
public String avatar; 
public String connection_type; 
public String thumb; 
public String small; 
public String first_name; 
public String last_name; 
public String no_of_user; 
public int grpIndex; 

public ContactsData(String name, String id, String email, String avatar, String connection_type) 
{ 
    this.name = name; 
    this.id = id; 
    this.email = email; 
    this.avatar = avatar; 
    this.connection_type = connection_type; 

} 
} 

Tutaj contactsList jest:

public static ArrayList<ContactsData> contactsList = new ArrayList<ContactsData>(); 
+1

jesteś najlepszym człowiekiem, dziękuję bardzo –

0

modelu Klasa:

public class ToDoModel implements Comparable<ToDoModel> { 
    private String id; 
    private Date taskDate; 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public Date getTaskDate() { 
     return taskDate; 
    } 

    public void setTaskDate(Date taskDate) { 
     this.taskDate = taskDate; 
    } 

    @Override 
    public int compareTo(ToDoModel another) { 
     return getTaskDate().compareTo(another.getTaskDate()); 
    } 
} 

teraz ustawić dane w ArrayList

for (int i = 0; i < your_array_length; i++) { 
    ToDoModel tm = new ToDoModel(); 
    tm.setId(your_id); 
    tm.setTaskDate(your_date); 
    mArrayList.add(tm); 
} 

Teraz Sortuj ArrayList

Collections.sort(toDoList); 

Podsumowanie: To posortować dane datewise

12

Teraz nie ma potrzeby boksu (czyli nie ma potrzeby tworzenia OBJECT użyciu nowego zastosowania Operator valueOf Insted z porównaniem Kolekcje.Sort ..)

1) Dla rosnącej kolejności

Collections.sort(temp, new Comparator<XYZBean>() 
{ 
    @Override 
    public int compare(XYZBean lhs, XYZBean rhs) { 

     return Integer.valueOf(lhs.getDistance()).compareTo(rhs.getDistance()); 
     } 
}); 

1) Dla Deascending celu

Collections.sort(temp, new Comparator<XYZBean>() 
{ 
    @Override 
    public int compare(XYZBean lhs, XYZBean rhs) { 

     return Integer.valueOf(rhs.getDistance()).compareTo(lhs.getDistance()); 
     } 
}); 
Powiązane problemy