Android-java- Como classificar uma lista de objetos por um determinado valor dentro do objeto


112

Estou tentando classificar uma lista de objetos por um valor específico dentro do objeto. Qual seria a melhor abordagem para fazer tal coisa. Devo usar Collections.sort () com algum tipo de comparador?

Estou tentando classificar uma lista de objetos por um valor flutuante que eles mantêm em uma das variáveis.

EDIT: Isto é o que eu tenho até agora:

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

os estados de erro: Não é possível invocar compareTo (double) no tipo primitivo double.

É porque um comparador não pode retornar nada além de um certo tipo?


2
"Devo usar Collections.sort () com algum tipo de comparador?" Sim, parece uma boa ideia
Kennet

Não sei se isso importa, mas o número de objetos na lista será tão alto quanto 80. É por isso que estou meio confuso sobre o uso de um comparador se esse for o caminho a percorrer, porque ele só compara dois valores de uma vez.
James andresakis

É assim que funciona a classificação. Primeiro adicione um item a uma lista. Ao adicionar próximo; deve ir antes ou depois do atual na lista. Ao adicionar o terceiro item, compare com o primeiro item da lista, se depois, compare com o próximo item. E assim por diante.
Kennet

Respostas:


98

Você deve usar Comparable em vez de um Comparator se uma classificação padrão for o que você está procurando.

Veja aqui, isso pode ser de alguma ajuda - Quando uma classe deve ser comparável e / ou comparadora?

Experimente isto -

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

Ei, obrigado pelo link :) Eu vou e voltarei de um idioma para o outro, então estou sempre perdendo alguma coisa: p você sabe como vai ...... pau para toda obra, mas não
sou

365

Siga este código para classificar qualquer 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
Esta deve ser a melhor resposta!
John Smith,

3
resposta simples e ótima, parabéns mano :)
Sadashiv

1
Simples e pequeno .. Obrigado!
Conheça Vora em

1
Isso parece muito limpo. obrigado. E um plus para dicas fornecidas.
Anurag

2
Trabalho apenas para API 24 e superior
Themelis

42

Eu acho que isso vai te ajudar melhor

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

Agora não há necessidade de boxe (ou seja, não há necessidade de criar OBJECTusando o novo valor de uso do operador em vez de compararTo de Collections.Sort ..)

1) Para ordem crescente

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

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

1) Para ordem Deascendente

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" aqui não é diferente de "java normal", então sim Collections.sort()seria uma boa abordagem.


1
Mas como faço para classificar por um valor dentro do objeto. Isso é o que estou preso.
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;

Como usar:

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

2

Você pode comparar duas String usando isto.

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

                    }

                });

E agora faça uma 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;

}
}

Aqui, a lista de contatos é:

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

1

Faça um Comparatorque possa comparar seus objetos ou, se todos forem instâncias da mesma classe, você pode fazer com que essa classe implemente Comparable. Você pode então usar Collections.sort () para fazer a classificação real.


Fui em frente e implementei Comparable na minha classe, mas criei um método para chamar sort na lista quando preciso classificá-la, mas como faço para classificá-la por um valor com no objeto?
James andresakis

O compareTo()método é onde você faz a comparação. Uma pequena pesquisa no Google deu vários exemplos detalhados de como usá-lo, aqui está um deles: javadeveloper.co.in/java-example/java-comparable-example.html
Jave

Eu configurei um método semelhante ao exemplo, mas recebo um erro informando que não posso usar compareTo em um elenco duplo. Parece que, por qualquer motivo, o que estou fazendo não gosta. Não é possível invocar compareTo (double) no tipo primitivo double. Vou adicionar meu código acima para mostrar o que quero dizer
James andresakis

1

Para Kotlin , você pode usar esta função

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

e basta chamá-lo em seu activityou fragmentpor

sortList(list)

0

Eu tenho um listview que mostra as informações sobre todos os clientes que estou classificando o nome dos clientes usando esta classe de comparação personalizada. Eles estão tendo algumas letras extras além das letras em inglês que estou gerenciando com este 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);*/

0

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

Agora defina os dados em 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);
}

Agora Classifique ArrayList

Collections.sort(toDoList);

Resumo: Ele classificará seus dados de acordo com a data


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.