Android-java: cómo ordenar una lista de objetos por un cierto valor dentro del objeto

112

Estoy tratando de clasificar una lista de matrices de objetos por un valor particular dentro del objeto. ¿Cuál sería el mejor enfoque para hacer tal cosa? ¿Debo usar Collections.sort () con algún tipo de comparador?

Estoy tratando de ordenar una lista de objetos por un valor flotante que contienen en una de las variables.

EDITAR: Esto es lo que tengo hasta ahora:

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

el error dice: No se puede invocar compareTo (double) en el tipo primitivo double.

¿Es porque un comparador no puede devolver nada más que un tipo determinado?

James andresakis
fuente
2
"¿Debo usar Collections.sort () con algún tipo de comparador?" Sí, suena como una buena idea
Kennet
No sé si importa, pero el número de objetos en la lista será tan alto como 80. Es por eso que estoy un poco confundido acerca de usar un comparador si ese es el camino a seguir porque solo compara dos valores a la vez.
James andresakis
Así es como funciona la clasificación. Primero agregue un elemento a una lista. Al agregar siguiente; debe ir antes o después de la actual en la lista. Al agregar el tercer elemento, compare con el primer elemento de la lista, si es posterior, compare con el siguiente elemento. Y así.
Kennet

Respuestas:

98

Debe usar Comparable en lugar de Comparator si lo que busca es una clasificación predeterminada.

Vea aquí, esto puede ser de alguna ayuda - ¿ Cuándo debería una clase ser Comparable y / o Comparator?

Prueba esto -

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;
    }
}
cielo azul
fuente
Hola, gracias por el enlace :) Voy y vengo de un idioma a otro, así que siempre me estoy perdiendo algo: p ya sabes cómo va ... Jack de todos los oficios, pero un maestro de ninguno lol
James andresakis
365

Siga este código para ordenar cualquier 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
fuente
16
¡Esta debería ser la mejor respuesta!
John Smith
3
respuesta simple y excelente, felicitaciones hermano :)
Sadashiv
1
Sencillo y pequeño .. ¡Gracias!
Conoce a Vora
1
Esto parece realmente limpio. Gracias. Y un plus por los consejos proporcionados.
Anurag
2
Trabajo solo para API 24 y superior
Themelis
42

Creo que esto te ayudará mejor

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
fuente
24

Ahora no es necesario boxear (es decir, no es necesario crear OBJECT usando el nuevo operador use valueOf insted con compareTo of Collections.Sort ..)

1) Por orden ascendente

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

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

1) Por orden descendente

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

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

"Android-java" aquí no es diferente de "java normal", por lo que sí Collections.sort()sería un buen enfoque.

Heiko Rupp
fuente
1
Pero, ¿cómo hago para ordenar por un valor dentro del objeto? Eso es en lo que estoy atrapado.
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;

Cómo utilizar:

Collections.sort(arraylist, new DateComparator());
Ketan Mehta
fuente
2

Puedes comparar dos String usando esto.

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

                    }

                });

Y ahora crea una clase 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;

}
}

Aquí la lista de contactos es:

public static ArrayList<ContactsData> contactsList = new ArrayList<ContactsData>();
Ankit Sharma
fuente
1

O haga un Comparatorque pueda comparar sus objetos, o si todos son instancias de la misma clase, puede hacer que esa clase se implemente Comparable. Luego puede usar Collections.sort () para hacer la clasificación real.

Jave
fuente
Seguí adelante e implementé Comparable en mi clase, pero creé un método para llamar a sort en la lista cuando necesito ordenarlo, pero ¿cómo lo ordeno por un valor en el objeto?
James andresakis
El compareTo()método -es donde haces la comparación. Un poco de búsqueda en Google dio varios ejemplos detallados sobre cómo usarlo, aquí está uno de ellos: javadeveloper.co.in/java-example/java-comparable-example.html
Jave
Configuré un método similar al ejemplo, sin embargo, obtengo un error que indica que no puedo usar compareTo en un cast double. Parece que por alguna razón, lo que estoy haciendo no le gusta. No se puede invocar compareTo (double) en el tipo primitivo double. Agregaré mi código arriba para mostrar lo que quiero decir
James andresakis
1

Clase de modelo:

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

Ahora configure los datos en 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);
}

Ahora ordenar ArrayList

Collections.sort(toDoList);

Resumen: Ordenará sus datos por fecha

Hiren Patel
fuente
1

Para Kotlin , puede utilizar esta función

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

y solo llámalo en tu activityo fragmentpor

sortList(list)
Kishan Solanki
fuente
0

Tengo una vista de lista que muestra la información sobre todos los clientes. Estoy ordenando el nombre de los clientes usando esta clase de comparación personalizada. Están teniendo algo de lectura adicional además de las letras en inglés que estoy manejando con este conjunto Fuerza (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);*/
DropAndTrap
fuente
0

¡Es muy fácil para Kotlin!

listToBeSorted.sortBy { it.distance }

Musab Gültekin
fuente