Comment sortinger la liste des objects par une propriété

J’ai classe simple

public class ActiveAlarm { public long timeStarted; public long timeEnded; private Ssortingng name = ""; private Ssortingng description = ""; private Ssortingng event; private boolean live = false; } 

et List con. Comment sortinger dans l’ordre croissant par timeStarted , puis par timeEnded ? Quelqu’un peut-il aider? Je connais en C ++ avec un algorithme générique et un opérateur de surcharge <, mais je suis nouveau sur Java.

Soit ActiveAlarm implémente Comparable ou implémente Comparator dans une classe distincte. Alors appelez:

 Collections.sort(list); 

ou

 Collections.sort(list, comparator); 

En général, c’est une bonne idée d’implémenter Comparable s’il y a un seul ordre de sorting “naturel” … sinon (si vous voulez sortinger dans un ordre particulier, mais peut tout aussi facilement en choisir un différent) mettre en œuvre le Comparator . Pour être honnête, cette situation particulière pourrait aller dans les deux sens, mais je maintiendrais probablement l’option Comparator plus flexible.

EDIT: Exemple d’implémentation:

 public class AlarmByTimesComparer implements Comparator { @Override public int compare(ActiveAlarm x, ActiveAlarm y) { // TODO: Handle null x or y values int startComparison = compare(x.timeStarted, y.timeStarted); return startComparison != 0 ? startComparison : compare(x.timeEnded, y.timeEnded); } // I don't know why this isn't in Long... private static int compare(long a, long b) { return a < b ? -1 : a > b ? 1 : 0; } } 

Utilisation du Comparator

Par exemple:

 class Score { private Ssortingng name; private List scores; // +accessor methods } 

  Collections.sort(scores, new Comparator() { public int compare(Score o1, Score o2) { // compare two instance of `Score` and return `int` as result. return o2.getScores().get(0).compareTo(o1.getScores().get(0)); } }); 

Avec Java 8, vous pouvez simplement utiliser l’expression lambda pour représenter l’instance du comparateur.

 Collections.sort(scores, (s1, s2) -> { /* compute and return int */ }); 

JAVA 8 and Above Answer (Utilisation des expressions lambda)

Dans Java 8, les expressions Lambda ont été introduites pour rendre cela encore plus facile! Au lieu de créer un object Comparator () avec tout son échafaudage, vous pouvez le simplifier comme suit: (Utilisation de votre object comme exemple)

 Collections.sort(list, (ActiveAlarm a1, ActiveAlarm a2) -> a1.timeStarted-a2.timeStarted); 

ou même plus court:

 Collections.sort(list, Comparator.comparingInt(ActiveAlarm ::getterMethod)); 

Cette déclaration est équivalente à la suivante:

 Collections.sort(list, new Comparator() { @Override public int compare(ActiveAlarm a1, ActiveAlarm a2) { return a1.timeStarted - a2.timeStarted; } }); 

Considérez les expressions Lambda comme exigeant uniquement que vous introduisiez les parties appropriées du code: la signature de la méthode et ce qui est renvoyé.

Une autre partie de votre question portait sur la comparaison avec plusieurs champs. Pour ce faire avec les expressions Lambda, vous pouvez utiliser la fonction .thenComparing() pour combiner efficacement deux comparaisons:

 Collections.sort(list, (ActiveAlarm a1, ActiveAlarm a2) -> a1.timeStarted-a2.timeStarted .thenComparing ((ActiveAlarm a1, ActiveAlarm a2) -> a1.timeEnded-a2.timeEnded) ); 

Le code ci-dessus va sortinger la liste d’abord par timeStarted , puis par timeEnded (pour les enregistrements ayant le même temps timeStarted ).

Une dernière remarque: il est facile de comparer les primitives «longues» ou «int», vous pouvez simplement les soustraire les unes des autres. Si vous comparez des objects (‘Long’ ou ‘Ssortingng’), je vous suggère d’utiliser leur comparaison intégrée. Exemple:

 Collections.sort(list, (ActiveAlarm a1, ActiveAlarm a2) -> a1.name.compareTo(a2.name) ); 

EDIT: Merci à Lukas Eder de m’avoir orienté vers la fonction .thenComparing() .

Nous pouvons sortinger la liste de deux manières:

1. Utilisation de Comparator : Lorsque vous devez utiliser la logique de sorting à plusieurs endroits Si vous souhaitez utiliser la logique de sorting à un endroit unique, vous pouvez écrire une classe interne anonyme comme suit ou extraire le comparateur et l’utiliser à plusieurs endroits.

  Collections.sort(arrayList, new Comparator() { public int compare(ActiveAlarm o1, ActiveAlarm o2) { //Sorts by 'TimeStarted' property return o1.getTimeStarted()o2.getTimeStarted()?1:doSecodaryOrderSort(o1,o2); } //If 'TimeStarted' property is equal sorts by 'TimeEnded' property public int doSecodaryOrderSort(ActiveAlarm o1,ActiveAlarm o2) { return o1.getTimeEnded()o2.getTimeEnded()?1:0; } }); 

Nous pouvons avoir une vérification nulle pour les propriétés, si nous avons pu utiliser «Long» au lieu de «long».

2. Utilisation de Comparable (ordre naturel) : si l’algorithme de sorting s’applique toujours à une propriété: écrivez une classe qui implémente la méthode «Comparable» et remplacez la méthode «Comparaison» comme définie ci-dessous

 class ActiveAlarm implements Comparable{ public long timeStarted; public long timeEnded; private Ssortingng name = ""; private Ssortingng description = ""; private Ssortingng event; private boolean live = false; public ActiveAlarm(long timeStarted,long timeEnded) { this.timeStarted=timeStarted; this.timeEnded=timeEnded; } public long getTimeStarted() { return timeStarted; } public long getTimeEnded() { return timeEnded; } public int compareTo(ActiveAlarm o) { return timeStartedo.getTimeStarted()?1:doSecodaryOrderSort(o); } public int doSecodaryOrderSort(ActiveAlarm o) { return timeEndedo.getTimeEnded()?1:0; } 

}

méthode de sorting d’appel pour sortinger en fonction de l’ordre naturel

 Collections.sort(list); 
 public class ActiveAlarm implements Comparable { public long timeStarted; public long timeEnded; private Ssortingng name = ""; private Ssortingng description = ""; private Ssortingng event; private boolean live = false; public int compareTo(ActiveAlarm a) { if ( this.timeStarted > a.timeStarted ) return 1; else if ( this.timeStarted < a.timeStarted ) return -1; else { if ( this.timeEnded > a.timeEnded ) return 1; else return -1; } } 

Cela devrait vous donner une idée approximative. Une fois cela fait, vous pouvez appeler Collections.sort() dans la liste.

Depuis Java8, cela peut être fait encore plus propre en combinant des Lambda expressions Comparator et Lambda expressions

Par exemple:

 class Student{ private Ssortingng name; private List scores; // +accessor methods } class Score { private int grade; // +accessor methods } 

  Collections.sort(student.getScores(), Comparator.comparing(Score::getGrade); 

En java8 + cela peut être écrit en une seule ligne comme suit,

collectionObjec.sort (comparator_lamda) ou comparator.comparing (CollectionType :: getterOfProperty)

code:

 ListOfActiveAlarmObj.sort((a,b->a.getTimeStarted().compareTo(b.getTimeStarted()))) 

ou

 ListOfActiveAlarmObj.sort(Comparator.comparing(ActiveAlarm::getTimeStarted)) 

En Java, vous devez utiliser la méthode Collections.sort statique. Voici un exemple pour une liste d’objects CompanyRole, sortingés d’abord par begin puis par fin. Vous pouvez facilement adapter pour votre propre object.

 private static void order(List roles) { Collections.sort(roles, new Comparator() { public int compare(Object o1, Object o2) { int x1 = ((CompanyRole) o1).getBegin(); int x2 = ((CompanyRole) o2).getBegin(); if (x1 != x2) { return x1 - x2; } else { int y1 = ((CompanyRole) o1).getEnd(); int y2 = ((CompanyRole) o2).getEnd(); return y2 - y1; } } }); } 

La liste sera maintenant sortingée 🙂

Guava’s ComparisonChain :

 Collections.sort(list, new Comparator(){ @Override public int compare(ActiveAlarm a1, ActiveAlarm a2) { return ComparisonChain.start() .compare(a1.timestarted, a2.timestarted) //... .compare(a1.timeEnded, a1.timeEnded).result(); }}); 

Vous pouvez appeler Collections.sort () et passer un comparateur que vous devez écrire pour comparer différentes propriétés de l’object.

Vous pouvez utiliser Collections.sort et passer votre propre Comparator

Comme mentionné, vous pouvez sortinger par:

  • Mettre en œuvre votre object Comparable
  • Ou passer un Comparator à Collections.sort

Si vous faites les deux, le Comparable sera ignoré et le Comparator sera utilisé. Cela aide les objects de valeur à avoir leur propre Comparable logique, ce qui est le type le plus raisonnable pour votre object de valeur, tandis que chaque cas d’utilisation a sa propre implémentation.