Android-java - Jak sortować listę obiektów według określonej wartości w obiekcie

112

Próbuję posortować tablicę obiektów według określonej wartości w obiekcie. Jakie byłoby najlepsze podejście do zrobienia takiej rzeczy. Czy powinienem używać Collections.sort () z jakimś komparatorem?

Próbuję posortować listę obiektów według wartości typu float, które przechowują w jednej ze zmiennych.

EDYCJA: To, co mam do tej pory:

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

błąd stwierdza: Nie można wywołać funkcji compareTo (double) na typie pierwotnym double.

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

James andresakis
źródło
2
„Czy powinienem używać Collections.sort () z jakimś komparatorem?” Tak, brzmi to jak dobry pomysł
Kennet,
Nie wiem, czy to ma znaczenie, ale liczba obiektów na liście będzie wynosić aż 80. To dlatego jestem trochę zdezorientowany, jeśli chodzi o używanie komparatora, jeśli jest to właściwy sposób, ponieważ porównuje on tylko dwie wartości na raz.
James andresakis
Tak działa sortowanie. Najpierw dodaj jedną pozycję do listy. Podczas dodawania następnego; powinno to nastąpić przed lub po bieżącym na liście. Dodając trzecią pozycję, porównaj z pierwszą pozycją na liście, a następnie porównaj z kolejną pozycją. I tak dalej.
Kennet

Odpowiedzi:

98

Powinieneś użyć Porównywalny zamiast Komparatora, jeśli szukasz domyślnego sortowania.

Zobacz tutaj, może to trochę pomóc - Kiedy klasa powinna być porównywalna i / lub komparatorowa?

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;
    }
}
niebieskie niebo
źródło
Hej dzięki za linka :) ja tam iz powrotem z jednego języka na drugi, tak Im zawsze czegoś brakuje: P wiesz jak to idzie ...... gniazdem wszystkich branż, ale mistrzem żaden lol
James andresakis
365

Postępuj zgodnie z tym kodem, aby posortować dowolną 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(Integer.valueOf(obj2.empId)); // To compare integer values

        // ## Descending order
        // return obj2.firstName.compareToIgnoreCase(obj1.firstName); // To compare string values
        // return Integer.valueOf(obj2.empId).compareTo(Integer.valueOf(obj1.empId)); // To compare integer values
        }
    });
Atif Mahmood
źródło
16
To powinna być najlepsza odpowiedź!
John Smith
3
prosta i świetna odpowiedź, kudos bro :)
Sadashiv
1
Prosty i mały… Dzięki!
Spotkaj się z Vorą
1
To wydaje się naprawdę czyste. dzięki. I jeden plus za udzielone wskazówki.
Anurag
2
Działa
42

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());
    }
});
Ramesh Solanki
źródło
24

Teraz nie ma potrzeby boksu (tj. Nie ma potrzeby tworzenia OBJECTprzy użyciu nowego operatora, użyj valueOf wstawionego z compareTo of Collections.Sort ..)

1) W porządku rosnącym

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

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

1) Dla porządku rosnącego

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

       return Integer.valueOf(rhs.getDistance()).compareTo(lhs.getDistance());
      }
 });
Pranav
źródło
2

„Android-java” nie różni się tutaj w żaden sposób od „normalnej java”, więc tak Collections.sort()byłoby dobrym podejściem.

Heiko Rupp
źródło
1
Ale jak mam posortować je według wartości w obiekcie. To jest to, na czym utknąłem.
James andresakis
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());
Ketan Mehta
źródło
2

Możesz porównać dwa ciągi, używając tego.

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);

                    }

                });

A teraz utwórz 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 lista kontaktów to:

public static ArrayList<ContactsData> contactsList = new ArrayList<ContactsData>();
Ankit Sharma
źródło
1

Albo stwórz coś, Comparatorco może porównać twoje obiekty, albo jeśli wszystkie są instancjami tej samej klasy, możesz sprawić, by klasa była implementowana Comparable. Następnie możesz użyć Collections.sort () do właściwego sortowania.

Jave
źródło
Poszedłem do przodu i zaimplementowałem Comparable w mojej klasie, ale i stworzyłem metodę wywoływania sortowania na liście, gdy muszę ją posortować, ale jak posortować ją według wartości w obiekcie?
James andresakis
Metoda compareTo()-metoda to miejsce, w którym wykonujesz porównanie. Trochę googlowania podało kilka szczegółowych przykładów, jak go używać, oto jeden z nich: javadeveloper.co.in/java-example/java-comparable-example.html
Jave
Ustawiłem metodę podobną do przykładu, ale pojawia się błąd z informacją, że nie mogę użyć funkcji compareTo na podwójnym rzutowaniu. Wygląda na to, że z jakiegokolwiek powodu nie podoba mi się to, co robię. Nie można wywołać funkcji compareTo (double) w typie pierwotnym double. Dodam swój kod powyżej, aby pokazać, o co mi chodzi
James andresakis
1

Klasa modelu:

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 ustaw 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: posortuje dane według danych

Hiren Patel
źródło
1

W przypadku Kotlina możesz użyć tej funkcji

fun sortList(list: List<YourCustomPOJOClass?>) {

    //descending
    Collections.sort(
        list
    ) { o1, o2 -> Integer.valueOf(o1!!.intValueXYZ!!).compareTo(o2!!.intValueXYZ!!) }

//    //ascending
//    Collections.sort(
//        list
//    ) { o1, o2 -> Integer.valueOf(o2!!.intValueXYZ!!).compareTo(o1!!.intValueXYZ!!) }
}

i po prostu zadzwoń do tego w swoim activitylub fragmentprzez

sortList(list)
Kishan Solanki
źródło
0

Mam widok listy, który pokazuje informacje o wszystkich klientach. Sortuję nazwy klientów przy użyciu tej niestandardowej klasy porównawczej. Oprócz angielskich liter, którymi zarządzam za pomocą tego setStrength (Collator.

 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);*/
DropAndTrap
źródło
0

Dla Kotlina to bardzo proste!

listToBeSorted.sortBy { it.distance }

Musab Gültekin
źródło