Ordenar ArrayList de objects personalizados por propriedade

Eu li sobre a sorting de ArrayLists usando um comparador, mas em todos os exemplos que as pessoas usaram compareTo que, de acordo com algumas pesquisas, é um método para Strings.

Eu queria classificar uma ArrayList de objects personalizados por uma das suas propriedades: um object Date ( getStartDay() ). Normalmente eu os comparo por item1.getStartDate().before(item2.getStartDate()) então eu estava pensando se poderia escrever 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); ... } 

Desde Date implementa Comparable , ele tem um método compareTo exatamente como String faz.

Portanto, seu Comparator personalizado poderia ser assim:

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

O método compare() deve retornar um int , então você não pode retornar diretamente um boolean como planejava.

Seu código de sorting seria exatamente como você escreveu:

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

Uma maneira um pouco mais curta de escrever tudo isso, se você não precisar reutilizar seu comparador, é escrevê-lo como uma class anônima in-line:

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

Desde java-8

Agora você pode escrever o último exemplo em um formato mais curto usando uma expressão lambda para o Comparator :

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

E List tem um método de sort(Comparator) , então você pode encurtar isso ainda mais:

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

Este é um idioma tão comum que existe um método embutido para gerar um Comparator para uma class com uma chave Comparable :

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

Todos estes são formas equivalentes.

Classes que têm uma ordem de sorting natural (uma class Number, como exemplo) devem implementar a interface Comparable, enquanto classs que não têm ordem de sorting natural (uma class Chair, por exemplo) devem ser fornecidas com um Comparator (ou um Comparador anônimo). class).

Dois exemplos:

 public class Number implements Comparable { 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 { public int compare(Chair chair1, Chair chair2) { return chair1.getWeight() - chair2.getWeight(); } } class ChairHeightComparator implements Comparator { public int compare(Chair chair1, Chair chair2) { return chair1.getHeight() - chair2.getHeight(); } } 

Uso:

 List numbers = new ArrayList(); ... Collections.sort(numbers); List chairs = new ArrayList(); // 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() { public int compare(Chair chair1, Chair chair2) { ... } }); 

Para classificar uma ArrayList você pode usar o seguinte trecho de código:

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

Sim você pode. Existem duas opções com a comparação de itens, a interface Comparável e a interface do Comparador .

Ambas as interfaces permitem um comportamento diferente. Comparable permite que você faça o object agir como você acabou de descrever Strings (na verdade, String implementa Comparable). O segundo, Comparator, permite que você faça o que você está pedindo para fazer. Você faria assim:

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

Isso fará com que o método Collections.sort use seu comparador para seu mecanismo de sorting. Se os objects da ArrayList forem implementados como comparáveis, você pode fazer algo assim:

 Collections.sort(myArrayList); 

A class Collections contém várias dessas ferramentas comuns e úteis.

Expressão lambda JAVA 8

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

OU

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

Com o Java 8, você pode usar uma referência de método para seu comparador:

 import static java.util.Comparator.comparing; Collections.sort(list, comparing(MyObject::getStartDate)); 
 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 { @Override public int compare(Person arg0, Person arg1) { return arg0.id - arg1.id; } } public static class CompDate implements Comparator { 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 people; people = new ArrayList(); 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()); } } } 

Como as tecnologias aparecem todos os dias, a resposta mudará no tempo. Eu dei uma olhada no LambdaJ e parece muito interessante.

Você pode tentar resolver essas tarefas com o LambdaJ . Você pode encontrá-lo aqui: http://code.google.com/p/lambdaj/

Aqui você tem um exemplo:

Ordenar Iterativo

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

Ordenar com lambda

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

Claro, ter esse tipo de beleza impacta no desempenho (em média 2 vezes), mas você pode encontrar um código mais legível?

Melhor maneira fácil com JAVA 8 é para o tipo alfabético Inglês

Implementação de Classe

 public class NewspaperClass implements Comparable{ public String name; @Override public int compareTo(NewspaperClass another) { return name.compareTo(another.name); } } 

Ordenar

  Collections.sort(Your List); 

Se você quiser classificar um alfabeto que contenha caracteres que não sejam em inglês, use Locale … Abaixo do código, use o tipo de caractere turco …

Implementação de Classe

 public class NewspaperClass implements Comparator { 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()); 

Do Java 8 diante, não precisamos usar Collections.sort() diretamente. List interface de List tem um método sort() padrão:

 List users = Arrays.asList(user1,user2,user3); users.sort( (u1, u2) -> { return u1.getFirstName.compareTo(u2.getFirstName());}); 

Veja http://visvv.blogspot.in/2016/01/sorting-objects-in-java-8.html .

Você pode usar o comparador de beans para classificar qualquer propriedade em sua class personalizada.

Você pode tentar o pedido de goiaba:

 Function getStartDate = new Function() { public Date apply(Item item) { return item.getStartDate(); } }; List orderedItems = Ordering.natural().onResultOf(getStartDate). sortedCopy(items); 

O Java 8 Lambda encurta o tipo.

 Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName())); 

Sim, isso é possível, por exemplo, nesta resposta eu classifico pela propriedade v da class IndexValue

  // Sorting by property v using a custom comparator. Arrays.sort( array, new Comparator(){ public int compare( IndexValue a, IndexValue b ){ return av - bv; } }); 

Se você perceber que estou criando uma class interna anônima (que é o Java para closures) e passando-a diretamente para o método de sort da class Arrays

Seu object também pode implementar o Comparable (que é o que o String e a maioria das bibliotecas principais em Java faz), mas isso definiria a “ordem de sorting natural” da própria class e não permitiria que você usasse novas.

Eu encontrei a maioria, se não todas essas respostas, dependem da class subjacente (Object) para implementar comparáveis ​​ou ter uma interface auxiliar auxiliar.

Não com a minha solução! O código a seguir permite comparar o campo do object, conhecendo o nome da string. Você pode facilmente modificá-lo para não usar o nome, mas precisa expor ou construir um dos Objetos com os quais deseja comparar.

 Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name")); public class ReflectiveComparator { public class FieldComparator implements Comparator { private String fieldName; public FieldComparator(String fieldName){ this.fieldName = fieldName; } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public int compare(Object object1, Object object2) { try { Field field = object1.getClass().getDeclaredField(fieldName); field.setAccessible(true); Comparable object1FieldValue = (Comparable) field.get(object1); Comparable object2FieldValue = (Comparable) field.get(object2); return object1FieldValue.compareTo(object2FieldValue); }catch (Exception e){} return 0; } } public class ListComparator implements Comparator { private String fieldName; public ListComparator(String fieldName) { this.fieldName = fieldName; } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public int compare(Object object1, Object object2) { try { Field field = object1.getClass().getDeclaredField(fieldName); field.setAccessible(true); Comparable o1FieldValue = (Comparable) field.get(object1); Comparable o2FieldValue = (Comparable) field.get(object2); if (o1FieldValue == null){ return -1;} if (o2FieldValue == null){ return 1;} return o1FieldValue.compareTo(o2FieldValue); } catch (NoSuchFieldException e) { throw new IllegalStateException("Field doesn't exist", e); } catch (IllegalAccessException e) { throw new IllegalStateException("Field inaccessible", e); } } } } 

Esses trechos de código podem ser úteis. Se você quiser classificar um object no meu caso eu quero ordenar por VolumeName:

 public List getSortedVolumes() throws SystemException { List volumes = VolumeLocalServiceUtil.getAllVolumes(); Collections.sort(volumes, new Comparator() { public int compare(Volume o1, Volume o2) { Volume p1 = (Volume) o1; Volume p2 = (Volume) o2; return p1.getVolumeName().compareToIgnoreCase( p2.getVolumeName()); } }); return volumes; } 

Isso funciona. Eu uso isso no meu jsp.

Você pode classificar usando java 8

 yourList.sort(Comparator.comparing(Classname::getName)); or yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue))); 

Você pode dar uma olhada nesta apresentação no Fórum Java em Stuttgart, Alemanha, em 2016.

Apenas alguns slides usam o idioma alemão, 99% do conteúdo é código-fonte em Java “baseado em inglês”; gostar

 someCollection.sort( OurCustomComparator .comparing(Person::getName) .thenComparing(Person::getId) ); 

onde OurCustomComparator está usando methods padrão (e outras idéias interessantes). Como mostrado, levando a um código muito conciso para escolher algum método getter para sorting; e super simples encadeamento (ou reversão) de critérios de sorting.

Se você está em java8, você encontra muito material lá para você começar.

Para o Java 8:

 Collections.sort(list, comparing(ClassName::getName)); 

ou

 Collections.sort(list, comparing(ClassName::getName).reversed()); 

Parece funcionar com o tipo de data String também como “2015-12-14T21: 55: 51Z”

Outra maneira é

 Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder()))); 

sua class customComparator deve implementar o java.util.Comparator para ser usado. ele também deve overide compare () AND equals ()

compare () deve responder a pergunta: O object 1 é menor, igual ou maior que o object 2?

documentos completos: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html

Com essa biblioteca, você pode classificar a lista de objects personalizados em várias colunas. A biblioteca usa resources da versão 8.0. Amostra também está disponível lá. Aqui está uma amostra para fazer

 SortKeys sortKeys = new SortKeys(); sortKeys.addField("firstName") .addField("age", true); // This (true) will sort the age descending // Other ways to specify a property to the sorter are // .addField("lastName", String.class); // .addField("dob", Date.class, true); // Instantiate a ListSorter ListSorter listSorter = new ListSorter(); // Pass the data to sort (listToSort) and the "by keys" to sort (sortKeys) List sortedList = (List) listSorter.sortList(listToSort, sortKeys); 

Eu prefiro este processo:

 public class SortUtil { public static  List sort(List list, String sortByProperty) { Collections.sort(list, new BeanComparator(sortByProperty)); return list; } } List sortedList = SortUtil.sort(unsortedList, "startDate"); 

Se você lista de objects tem uma propriedade chamada startDate , você chama de usar isso várias vezes. Você pode até startDate.time los startDate.time .

Isso requer que seu object seja Comparable que significa que você precisa de uma implementação compareTo , equals e hashCode .

Sim, poderia ser mais rápido … Mas agora você não precisa fazer um novo Comparador para cada tipo de sorting. Se você pode economizar tempo de desenvolvimento e desistir do tempo de execução, você pode escolher este.

Novo desde 1.8 é um método List.sort () em vez de usar o Collection.sort () para que você chame diretamente mylistcontainer.sort ()

Aqui está um trecho de código que demonstra o recurso List.sort ():

 List fruits = new ArrayList(); fruits.add(new Fruit("Kiwi","green",40)); fruits.add(new Fruit("Banana","yellow",100)); fruits.add(new Fruit("Apple","mixed green,red",120)); fruits.add(new Fruit("Cherry","red",10)); // a) using an existing compareto() method fruits.sort((Fruit f1,Fruit f2) -> f1.getFruitName().compareTo(f2.getFruitName())); System.out.println("Using String.compareTo(): " + fruits); //Using String.compareTo(): [Apple is: mixed green,red, Banana is: yellow, Cherry is: red, Kiwi is: green] // b) Using a comparable class fruits.sort((Fruit f1,Fruit f2) -> f1.compareTo(f2)); System.out.println("Using a Comparable Fruit class (sort by color): " + fruits); // Using a Comparable Fruit class (sort by color): [Kiwi is green, Apple is: mixed green,red, Cherry is: red, Banana is: yellow] 

A class de fruta é:

 public class Fruit implements Comparable { private String name; private String color; private int quantity; public Fruit(String name,String color,int quantity) { this.name = name; this.color = color; this.quantity = quantity;} public String getFruitName() { return name; } public String getColor() { return color; } public int getQuantity() { return quantity; } @Override public final int compareTo(Fruit f) // sorting the color { return this.color.compareTo(f.color); } @Override public String toString() { return (name + " is: " + color); } 

} // fim da class Fruit

Usar o uso do Java 8 pode definir o Comparator em uma linha usando Comparator.comparing()

Use qualquer uma das seguintes maneiras:

Opção 1:

 listToBeSorted.sort(Comparator.comparing(CustomObject::getStartDate)); 

Opção 2:

 Collections.sort(listToBeSorted, Comparator.comparing(CustomObject::getStartDate)); 
    Intereting Posts