[Java8] Utilisation appropriée de Compareable et Comparator du point de vue du tri des employés

Auto-introduction

Ravi de vous rencontrer, je m'appelle @ekuro et je crée un service de gestion du travail appelé Gozal. Chez Gozal, nous faisons du développement axé sur le domaine pour mieux intégrer la gestion du travail dans les logiciels. Nous sommes constamment à la recherche de classes meilleures et plus polyvalentes afin de pouvoir répondre facilement aux changements de processus métier dus aux réformes du style de travail.

Ce thème

Cette fois, j'ai réfléchi à «quoi utiliser» et «où définir» pour trier la liste des employés par numéro d'employé.

Ce que j'ai fait

supposition

Considérez le processus de tri de la liste des employés Liste des employés <Employee>; par numéro d'employé.

Employee.java


@Getter
@AllArgsConstructor
public class Employee {
  //numéro d'employé
  private EmployeeNumber number;
  //Informations personnelles telles que le nom et la date de naissance
  private Personal personal;
}

@Getter
@AllArgsConstructor
public class EmployeeNumber {
  private String number;
}

Méthode de tri

Les méthodes typiques de tri des objets dans Java 8 sont Collections.sort et la méthode Sorted de l'API Stream.

Lorsque vous utilisez des collections, vous devrez utiliser l'un des deux types de méthodes de tri suivants.

public static <T extends Comparable<? super T>> void sort(List<T> list) {
  list.sort(null);
}
public static <T> void sort(List<T> list, Comparator<? super T> c) {
  list.sort(c);
}

En outre, lors de l'utilisation de l'API Stream, deux types de méthodes sont également fournis.

Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);

Dans les deux cas, lors de l'utilisation de la première méthode, la classe à trier doit implémenter Compareable, et lors de l'utilisation de la seconde méthode, l'interface fonctionnelle Comparator est utilisée comme argument. Doit être transmis.

Comparable et Comparator sont des classes qui définissent les comparaisons de magnitude, mais examinons d'abord les différences.

Différence entre comparable et comparateur

Comparable est une interface dans laquelle seul public int compareTo (To); est défini. En héritant de Compareable à l'objet que vous souhaitez comparer et en implémentant compareTo, vous pouvez définir comment comparer cet objet. La méthode compareTo se compare à l'argument. D'autre part, l'interface Comparator définit une méthode qui a deux arguments, ʻint compare (To1, To2); `. Étant donné que vous pouvez implémenter plusieurs comparateurs pour les objets que vous souhaitez comparer, il est utile lorsque vous souhaitez définir le tri par différentes clés.

Pour l'employé

Prenons le cas de la classe Employee. La classe Employé contient des informations personnelles telles que le nom en plus du numéro d'employé. Par conséquent, il est possible de trier par diverses informations à l'avenir. Par conséquent, il semble préférable de créer un comparateur pour chaque élément à comparer au lieu d'hériter de Compareable dans la classe Employee.

Écrivons une méthode qui renvoie réellement un compositeur pour trier la liste d'employés par numéro d'employé. [^ 1]

Employee.java


@Getter
@AllArgsConstructor
public class Employee {
  //numéro d'employé
  private EmployeeNumber number;
  //Informations personnelles telles que le nom et la date de naissance
  private Personal personal;

  public static Comparator<Employee> orderByNumber() {
    return Comparator.comparing(
      //Comparaison simple des chaînes de numéros d'employés
      (Employee employee) -> employee.getNumber().getNumber());
  }
}

Si vous triez réellement

List<Employee> employees = ~;
Collections.sort(employees, Employee.orderByNumber());

Peut être écrit.

Effectuer le traitement de comparaison à l'endroit approprié

Dans l'exemple ci-dessus, la méthode de comparaison ʻorderByNumber () `est définie dans la classe Employee. Cependant, par nature, la comparaison des nombres d'employés est une propriété que les classes de nombres d'employés devraient avoir. Déplacez donc la méthode de comparaison vers la classe EmployeeNumber.

Employee.java


@Getter
@AllArgsConstructor
public class Employee {
  //numéro d'employé
  private EmployeeNumber number;
  //Informations personnelles telles que le nom et la date de naissance
  private Personal personal;

  public static Comparator<Employee> orderByNumber() {
    //En utilisant EmployeeNumber comme clé de comparaison, le processus de tri est laissé à la méthode de commande de EmployeeNumber.
    return Comparator.comparing(Employee::getNumber, EmployeeNumber.order());
  }
}

EmployeeNumber.java


@Getter
@AllArgsConstructor
public class EmployeeNumber {
  private String number;
  
  public static Comparator<EmployeeNumber> order() {
    return Comparator.comparing(EmployeeNumber::getNumber);
  }
}

La méthode de traitement de comparaison a été complétée avec EmployeeNumber, ce qui en fait une classe plus polyvalente. Cette fois, le processus de comparaison de taille de EmployeeNumber est une logique simple, mais si les nombres et les chaînes de caractères sont mélangés, cela devient un processus un peu compliqué. Dans ce cas, il est préférable d'avoir un processus de comparaison défini dans EmployeeNumber.

Détrompez-vous si vous pouvez utiliser Comparable

Étant donné que plusieurs comparateurs peuvent être définis pour un objet, il est facile de les utiliser beaucoup. Vérifiez donc si vous avez utilisé Comparer où vous devez hériter de Comparable.

Il semble que le tri du numéro d'employé cette fois ne sera pas trié par autre que le nombre à l'avenir. Par conséquent, il est préférable d'utiliser Comparable pour le traitement de comparaison du nombre d'employés.

Employee.java


@Getter
@AllArgsConstructor
public class Employee {
  //numéro d'employé
  private EmployeeNumber number;
  //Informations personnelles telles que le nom et la date de naissance
  private Personal personal;

  public static Comparator<Employee> orderByNumber() {
    //EmployeeNumber implémente Comparable, ce qui réduit le nombre d'arguments.
    return Comparator.comparing(Employee::getNumber);
  }
}

EmployeeNumber.java


@Getter
@AllArgsConstructor
public class EmployeeNumber implements Comparable<EmployeeNumber> {
  private String number;
  
  @Override
  public int compareTo(@Nonnull EmployeeNumber other) {
    return this.number.compareTo(other.number);
  }
}

En héritant de Comparable de EmployeeNumber, toute description inutile est éliminée et le contenu de traitement est affiné.

En écrivant le traitement approprié à l'endroit approprié de cette manière, il sera possible de répondre en douceur à des demandes telles que «Je veux trier par nom» et «Je veux trier par anniversaire» à l'avenir.

Nous pensons qu'une meilleure compréhension des concepts et la conception de classes faciliteront non seulement l'implémentation et la fourniture d'un code source facile à comprendre, mais conduiront également à la découverte de nouveaux flux commerciaux plus sophistiqués.

Chez Gozal, afin de créer une nouvelle expérience de travail qui rendra le monde étonnant en envoyant des ingénieurs, nous nous en tiendrons à la façon d'appréhender le concept.

Recrutement d'ingénieurs du monde de la gestion du travail pour éliminer le travail manuel inutile! Recrutement d'ingénieurs frontaux pour créer un SaaS de gestion du travail mobile!

[^ 1]: La méthode de comparaison statique fournie dans l'interface Comparator prend une Function comme argument et compare le résultat de Function avec compareTo lorsqu'il n'y a qu'un seul argument.

Recommended Posts

[Java8] Utilisation appropriée de Compareable et Comparator du point de vue du tri des employés
Utilisation correcte de la classe abstraite et de l'interface en Java
Utilisez redirect_to et effectuez un rendu correctement
Utilisation correcte de Mockito et PowerMock
S'il faut utiliser Java Comparable ou Comparator
Utilisation correcte de l'interface et de la classe abstraite
Discrimination d'énum dans Java 7 et supérieur
(Déterminez en 1 minute) Comment utiliser vide?, Vide? Et présent?
[Java] Utilisation de final dans la déclaration de variable locale
Critères pour utiliser correctement render et redirect_to
Tri à l'aide du comparateur java
Utilisation de polices japonaises et de caractères étrangers dans Jasper Report
Utiliser OpenCV avec Java
Utiliser PreparedStatement en Java
Traitement de la date et de l'heure en Ruby. Utilisez correctement la date et l'heure.
[Pour les débutants] Explication des classes, des instances et des statiques en Java
Comment appeler et utiliser l'API en Java (Spring Boot)
Raisons d'utiliser séparément Servlet et JSP dans le développement Java
[Java] Comparateur de la classe Collection
Comparable et Comparator (commande d'objets)
Avantages et inconvénients de Java
Implémentation Java de tri-tree
[Java] Termes de base en programmation
Mécanisme et caractéristiques de la classe d'implémentation Collection souvent utilisés en Java
Utiliser java avec MSYS et Cygwin
À propos de Biocontainers fastqc et Java
Exemple d'encodage et de décodage en Java
Utilisons Twilio en Java! (Introduction)
Utilisez JDBC avec Java et Scala.
[Java] N'utilisez pas "+" dans append!
Utilisez des clés composites dans Java Maps.
Classe StringBuffer et StringBuilder en Java
Liste des membres ajoutés dans Java 9
Comprendre equals et hashCode en Java
Comment utiliser les classes en Java?
Liste des types ajoutés dans Java 9
Implémentation d'une fonction similaire en Java
Utilisez-vous Stream en Java?
Bonjour tout le monde en Java et Gradle
JSON en Java et Jackson Part ③ Incorporer JSON dans HTML et l'utiliser à partir de JavaScript
L'histoire de l'oubli de fermer un fichier en Java et de l'échec
Utiliser un bloc d'initialisation statique pour initialiser la liste / l'ensemble de champs statiques en Java
Tri par hachage AtCoder ABC 111 C résolu en Ruby, Perl et Java
Qu'est-ce qui n'était pas une utilisation équitable du détournement d'API Java sur Android?
Ceci et cela de la mise en œuvre du jugement en temps réel des dates en Java
Comparaison des méthodes d'implémentation de thread en Java et de la méthode d'expression lambda
[Java] Notez comment utiliser RecyclerView et comment implémenter le traitement par balayage animé.
Trouvez le maximum et le minimum des cinq nombres saisis en Java
Revue des connaissances «étranges Java» et Java souvent oubliées dans Java Bronze