Android-java - Comment trier une liste d'objets par une certaine valeur dans l'objet


112

Im essayant de trier une arraylist d'objets par une valeur particulière dans l'objet. Quelle serait la meilleure approche pour faire une telle chose. Dois-je utiliser Collections.sort () avec une sorte de comparateur?

Im essayant de trier une liste d'objets par une valeur flottante qu'ils détiennent dans l'une des variables.

EDIT: C'est ce que j'ai jusqu'à présent:

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

les états d'erreur: Impossible d'appeler compareTo (double) sur le type primitif double.

Est-ce parce qu'un comparateur ne peut pas renvoyer autre chose qu'un certain type?


2
"Dois-je utiliser Collections.sort () avec une sorte de comparateur?" Oui, ça semble être une bonne idée
Kennet

Je ne sais pas si cela compte mais le nombre d'objets dans la liste sera aussi élevé que 80. C'est pourquoi je suis un peu confus à propos de l'utilisation d'un comparateur si c'est la voie à suivre car il ne compare que deux valeurs à la fois.
James andresakis

C'est ainsi que fonctionne le tri. Ajoutez d'abord un élément à une liste. Lors de l'ajout suivant; devrait-il aller avant ou après le courant dans la liste. Lors de l'ajout d'un troisième élément, comparez au premier élément de la liste, si après, comparez à l'élément suivant. Etc.
Kennet

Réponses:


98

Vous devez utiliser Comparable au lieu d'un Comparator si vous recherchez un tri par défaut.

Voir ici, cela peut être utile - Quand une classe devrait-elle être comparable et / ou comparateur?

Essaye ça -

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

Hé merci pour le lien :) Je fais des allers-retours d'une langue à l'autre donc il me manque toujours quelque chose: p tu sais comment ça se passe ...... touche à tout mais maître de rien lol
James andresakis

365

Suivez ce code pour trier n'importe quel 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
        }
    });

16
Cela devrait être la meilleure réponse!
John Smith

3
réponse simple et excellente, bravo bro :)
Sadashiv

1
Simple et petit .. Merci!
Rencontrez Vora

1
Cela semble vraiment propre. Merci. Et un plus pour les conseils fournis.
Anurag

2
Fonctionne uniquement pour l'API 24 et plus
Themelis

42

Je pense que cela t'aidera mieux

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

24

Désormais pas besoin de boxe (c'est-à-dire pas besoin de créer OBJECT utilisant un nouvel opérateur utiliser valueOf insted avec compareTo de Collections.Sort ..)

1) Pour l'ordre croissant

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

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

1) Pour l'ordre décroissant

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

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

2

«Android-java» n'est ici en aucun cas différent de «Java normal», donc oui Collections.sort()serait une bonne approche.


1
Mais comment puis-je le faire trier par une valeur dans l'objet. C'est sur quoi je suis coincé.
James andresakis le

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;

Comment utiliser:

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

2

Vous pouvez comparer deux String en utilisant ceci.

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

                    }

                });

Et maintenant, créez une classe 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;

}
}

Ici contactsList est:

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

1

Soit vous créez un Comparatorqui peut comparer vos objets, soit si ce sont toutes des instances de la même classe, vous pouvez faire en sorte que cette classe soit implémentée Comparable. Vous pouvez ensuite utiliser Collections.sort () pour effectuer le tri réel.


Je suis allé de l'avant et j'ai implémenté Comparable dans ma classe, mais j'ai créé une méthode pour appeler le tri sur la liste lorsque j'ai besoin de le trier, mais comment puis-je le trier par une valeur dans l'objet?
James andresakis

La compareTo()méthode-est l'endroit où vous faites la comparaison. Un peu de googler a donné plusieurs exemples détaillés sur la façon de l'utiliser, en voici l'un: javadeveloper.co.in/java-example/java-comparable-example.html
Jave

J'ai mis en place une méthode similaire à l'exemple mais j'obtiens une erreur indiquant que je ne peux pas utiliser compareTo sur un double coulé. Il semble que pour n'importe quelle raison, ce que je fais n'aime pas. Impossible d'appeler compareTo (double) sur le type primitif double. Je vais ajouter mon code ci-dessus pour montrer ce que je veux dire
James andresakis

1

Classe de modèle:

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

Maintenant, définissez les données dans 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);
}

Trier maintenant ArrayList

Collections.sort(toDoList);

Résumé: il triera vos données par date


1

Pour Kotlin , vous pouvez utiliser cette fonction

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!!) }
}

et appelez-le simplement dans votre activityou fragmentpar

sortList(list)

0

J'ai une liste qui affiche les informations sur tous les clients que je trie le nom des clients à l'aide de cette classe de comparateur personnalisée. Ils ont un peu plus de lettres en plus des lettres anglaises que je gère avec cet ensemble Force (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);*/

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.