Utilizzo comparabile per più campi dinamici di VO in java

Ho una lezione

public class StudentVO { int age; String name; } 

Ho usato la stessa class in due aree diverse. In un posto ho bisogno di ordinare in base all’età. In un altro luogo ho bisogno di ordinare in base al nome e in un altro posto potrebbe essere necessario l’ordinamento in base all’età e al nome. Come posso fare questo? Se un campo posso sovrascrivere compareTo() .

È ansible farlo?

1) Dovresti scrivere due Comparator per ordinare separatamente età e nome, e quindi usare Collections.sort (List, Comparator) . Qualcosa come questo:

 class StudentVO { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } class AgeComparator implements Comparator { @Override public int compare(StudentVO o1, StudentVO o2) { Integer age1 = o1.getAge(); Integer age2 = o2.getAge(); return age1.compareTo(age2); } } class NameComparator implements Comparator { @Override public int compare(StudentVO o1, StudentVO o2) { return o1.getName().compareTo(o2.getName()); } } 

E poi usarli, per ordinare in base age :

 Collections.sort(list,new AgeComparator()); 

ordinare in base al name :

 Collections.sort(list,new NameComparator()); 

2) Se ritieni che l’ List di StudentVO abbia un ordine naturale di classificazione, supponi di ordinare per age . Quindi, usa Paragonabile per age e Comparator per name .

  class StudentVO implements Comparable{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int compareTo(StudentVO o) { return ((Integer)getAge()).compareTo(o.getAge()); } } class NameComparator implements Comparator { @Override public int compare(StudentVO o1, StudentVO o2) { return o1.getName().compareTo(o2.getName()); } } 

E poi usarli, per ordinare in base age :

 Collections.sort(list); 

ordinare in base al name :

 Collections.sort(list,new NameComparator()); 

C’è un nuovo approccio per questo in java-8 consultare Comparator # comparative e Comparator # thenComparing . Tutto ciò che serve è fornire un riferimento all’espressione / metodo lamda per il metodo Stream#sorted() o List#sort() .

Ad esempio l’ordinamento per un campo:

 List students = Arrays.asList( new StudentVO(20,"Bob"), new StudentVO(19, "Jane") ); // sort by age students.stream() .sorted(Comparator.comparing(StudentVO::getAge)) .forEach(System.out::println); // [StudentVO{age=19, name='Jane'},StudentVO{age=20, name='Bob'}] // sort by name students.stream() .sorted(Comparator.comparing(StudentVO::getName)) .forEach(System.out::println); // [StudentVO{age=20, name='Bob'}, StudentVO{age=19, name='Jane'}] 

Ordinamento per alcuni campi:

 List students = Arrays.asList( new StudentVO(20,"Bob"), new StudentVO(19, "Jane"), new StudentVO(21,"Bob") ); // by age and then by name students.stream() .sorted(Comparator .comparing(StudentVO::getAge) .thenComparing(StudentVO::getName) ).forEach(System.out::println); // [StudentVO{age=19, name='Jane'}, StudentVO{age=20, name='Bob'}, StudentVO{age=21, name='Bob'}] // by name an then by age students.stream() .sorted(Comparator .comparing(StudentVO::getName) .thenComparing(StudentVO::getAge) ).forEach(System.out::println); // [StudentVO{age=20, name='Bob'}, StudentVO{age=21, name='Bob'}, StudentVO{age=19, name='Jane'}] 

Ecco lo snippet di codice:

 public class StudentNameComparator implements Comparator{ @Override public int compare(StudentVO s1, StudentVO s2) { //ascending order return s1.getName().compareTo(s2.getName()); //descending order //return s2.getName().compareTo(s1.getName()); } } 

Secondo la tua domanda, funzionerà anche quando i valori del campo specificato cambieranno. Devi solo ricordare di chiamare il metodo di sort con questo comparatore.

In Java, hai due modi principali per confrontare gli oggetti. Il primo è che la class stessa implementa l’interfaccia Comparable che significherà solo una implementazione. Il secondo è che le classi implementino l’interfaccia di Comparator . In questo modo, puoi avere più comparatori per la stessa class.

Ciò significa che è ansible definire per esenti 3 comparatori diversi nella class StudentVo: uno che confronta solo il nome, un altro che confronta l’età e l’ultimo che entrambe le proprietà.

Nell’applicazione, si utilizza l’implementazione che si adatta alle proprie esigenze in base a ciò che si desidera confrontare. In un posto, confronterai gli studenti su Collections.sort (myStudents, new CompareStudentOnAge ()). In un altro luogo, usi un’altra implementazione.

Puoi trovare alcune spiegazioni in questo post del blog: http://javarevisited.blogspot.fr/2011/06/comparator-and-comparable-in-java.html

Recentemente ho dovuto risolvere anche questo problema. Non sono sicuro se questo è esattamente lo stesso scenario del tuo, ma ho dovuto scrivere un ordinamento in memoria per zero o più colonne di una griglia, tenendo in mano le condizioni di OOM, ecc., Perché il mio problema era molto limitato.

Ho scritto un comparatore per ogni colonna e un comparatore che ha preso una lista di comparatori. Quando ho identificato le colonne da ordinare e in quale ordine, ho aggiunto un’istanza del comparatore corrispondente all’elenco dei comparatori. Quindi, utilizzare il comparatore concatenato per eseguire l’ordinamento effettivo.

 public class MyObject { private String name; private int age; private Date registered; } 

Quindi, qualcosa come questo per ogni comparatore:

 public class NameComparator implements Comparator { public int compare(MyObject o1, MyObject o2) { return o1.getName().compareTo(o2.getName); } } 

Questo per il comparatore concatenato:

 public class ChainedComparator implements Comparator { public int compare(MyObject o1, MyObject o2) { for(Comparator comparator : comparators) { int result = comparator.compare(o1,o2); if(result != 0) { return result; } } return 0; } } private List> comparators = new ArrayList<>(); } 

Lasciato alla tua immaginazione sta analizzando il genere e costruendo il comparatore concatenato. In realtà ho reso questo un po ‘più complicato perché ho anche incorporato una direzione che ho implementato scambiando l’ordine dei parametri nella chiamata al sub-comparatore nel comparatore concatenato, se necessario.