Pregunta Sort ArrayList de objetos personalizados por propiedad


Leí sobre ordenar ArrayLists usando un Comparador pero en todos los ejemplos que las personas usaban compareTo que según algunas investigaciones es un método para Strings.

Quería ordenar una ArrayList de objetos personalizados por una de sus propiedades: un objeto Date (getStartDay()) Normalmente los comparo por item1.getStartDate().before(item2.getStartDate()) entonces me preguntaba si podría escribir algo como:

public class CustomComparator {
    public boolean compare(Object object1, Object object2) {
        return object1.getStartDate().before(object2.getStartDate());
    }
}

public class RandomName {
    ...
    Collections.sort(Database.arrayList, new CustomComparator);
    ...
}

952
2018-05-06 21:09


origen


Respuestas:


Ya que Date implementos Comparable, tiene un compareTo método al igual String hace.

Entonces tu costumbre Comparator podría verse así:

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

los compare() método debe devolver un int, por lo que no podría devolver directamente un boolean como si estuvieras planeando hacerlo de todos modos.

Su código de clasificación sería como usted escribió:

Collections.sort(Database.arrayList, new CustomComparator());

Una forma un poco más corta de escribir todo esto, si no necesita reutilizar su comparador, es escribirlo como una clase anónima en línea:

Collections.sort(Database.arrayList, new Comparator<MyObject>() {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getStartDate().compareTo(o2.getStartDate());
    }
});

Ya que

Ahora puede escribir el último ejemplo en una forma más corta usando un expresión lambda Para el Comparator:

Collections.sort(Database.arrayList, 
                        (o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

Y List tiene un sort(Comparator) método, por lo que puede acortar esto aún más:

Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

Esta es una expresión tan común que hay un método incorporado generar un Comparator para una clase con un Comparable llave:

Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));

Todos estos son formularios equivalentes.


1305
2018-05-06 21:18



Las clases que tienen un orden natural (un número de clase, como ejemplo) deben implementar la interfaz Comparable, mientras que las clases que no tienen un orden natural (una clase Chair, por ejemplo) deben proporcionarse con un Comparador (o un Comparador anónimo clase).

Dos ejemplos:

public class Number implements Comparable<Number> {
    private int value;

    public Number(int value) { this.value = value; }
    public int compareTo(Number anotherInstance) {
        return this.value - anotherInstance.value;
    }
}

public class Chair {
    private int weight;
    private int height;

    public Chair(int weight, int height) {
        this.weight = weight;
        this.height = height;
    }
    /* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
    public int compare(Chair chair1, Chair chair2) {
        return chair1.getWeight() - chair2.getWeight();
    }
}
class ChairHeightComparator implements Comparator<Chair> {
    public int compare(Chair chair1, Chair chair2) {
        return chair1.getHeight() - chair2.getHeight();
    }
}

Uso:

List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);

List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());

// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
    public int compare(Chair chair1, Chair chair2) {
        ...
    }
});

181
2018-05-06 21:45



Para clasificar un ArrayList podrías usar el siguiente fragmento de código:

Collections.sort(studList, new Comparator<Student>(){
    public int compare(Student s1, Student s2) {
        return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
    }
});

150
2018-05-06 13:50



Sí tu puedes. Hay dos opciones para comparar elementos, Comparable interfaz, y el Comparador interfaz.

Ambas interfaces permiten un comportamiento diferente. Comparable le permite hacer que el objeto actúe como acaba de describir Cadenas (de hecho, String implementa Comparable). El segundo, Comparador, le permite hacer lo que está pidiendo que haga. Lo harías así:

Collections.sort(myArrayList, new MyComparator());

Eso hará que el método Collections.sort use su comparador para su mecanismo de clasificación. Si los objetos de la ArrayList son comparables, en su lugar puede hacer algo como esto:

Collections.sort(myArrayList);

los Colecciones la clase contiene varias de estas útiles herramientas comunes.


40
2018-05-06 21:17



Expresión JAVA 8 lambda

Collections.sort(studList, (Student s1, Student s2) ->{
        return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});

O

Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c)

31
2017-09-05 13:10



Con Java 8 puede usar una referencia de método para su comparador:

import static java.util.Comparator.comparing;

Collections.sort(list, comparing(MyObject::getStartDate));

26
2018-03-13 15:19



import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;

public class test {

public static class Person {
    public String name;
    public int id;
    public Date hireDate;

    public Person(String iname, int iid, Date ihireDate) {
        name = iname;
        id = iid;
        hireDate = ihireDate;
    }

    public String toString() {
        return name + " " + id + " " + hireDate.toString();
    }

    // Comparator
    public static class CompId implements Comparator<Person> {
        @Override
        public int compare(Person arg0, Person arg1) {
            return arg0.id - arg1.id;
        }
    }

    public static class CompDate implements Comparator<Person> {
        private int mod = 1;
        public CompDate(boolean desc) {
            if (desc) mod =-1;
        }
        @Override
        public int compare(Person arg0, Person arg1) {
            return mod*arg0.hireDate.compareTo(arg1.hireDate);
        }
    }
}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
    ArrayList<Person> people;
    people = new ArrayList<Person>();
    try {
        people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
        people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
        people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Collections.sort(people, new Person.CompId());
    System.out.println("BY ID");
    for (Person p : people) {
        System.out.println(p.toString());
    }

    Collections.sort(people, new Person.CompDate(false));
    System.out.println("BY Date asc");
    for (Person p : people) {
        System.out.println(p.toString());
    }
    Collections.sort(people, new Person.CompDate(true));
    System.out.println("BY Date desc");
    for (Person p : people) {
        System.out.println(p.toString());
    }

}

}

13
2018-04-03 15:32



Dado que las tecnologías aparecen todos los días, la respuesta cambiará en el tiempo. Eché un vistazo a LambdaJ y parece muy interesante.

Puedes intentar resolver estas tareas con LambdaJ. Lo puedes encontrar aquí: http://code.google.com/p/lambdaj/

Aquí tienes un ejemplo:

Sort Iterative

List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
        public int compare(Person p1, Person p2) {
           return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
        }
});

Clasificar con lambda

List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge()); 

Por supuesto, tener este tipo de belleza impacta en el rendimiento (un promedio de 2 veces), pero ¿puedes encontrar un código más legible?


13
2018-03-12 17:49



La mejor manera fácil con JAVA 8 es para el orden alfabético inglés

Implementación de clase

public class NewspaperClass implements Comparable<NewspaperClass>{
   public String name;

   @Override
   public int compareTo(NewspaperClass another) {
      return name.compareTo(another.name);
   }
}

Ordenar

  Collections.sort(Your List);

Si desea ordenar el alfabeto que no contiene caracteres en inglés, puede usar la configuración regional ... A continuación, utilice el código de caracteres turco ...

Implementación de clase

public class NewspaperClass implements Comparator<NewspaperClass> {
   public String name;
   public Boolean isUserNewspaper=false;
   private Collator trCollator = Collator.getInstance(new Locale("tr_TR"));



   @Override
   public int compare(NewspaperClass lhs, NewspaperClass rhs) {
      trCollator.setStrength(Collator.PRIMARY);
      return trCollator.compare(lhs.name,rhs.name);
   }
}

Ordenar

Collections.sort(your array list,new NewspaperClass());

7
2018-05-28 12:11



Puedes usar el Comparador de frijoles para ordenar en cualquier propiedad en su clase personalizada.


5
2018-05-06 21:29