Java Méthode à usage général qui récupère uniquement les différences entre les propriétés des objets de la même classe

introduction

C'est comme String.equals ("A", "B"), il y a des comparaisons entre les objets, mais `Comment comparer les propriétés d'un objet et extraire les parties qui diffèrent? '' Je l'ai cherché.

Ce que je veux faire, c'est quand il y a un objet comme celui ci-dessous (Je pensais qu'il serait facile d'expliquer le contenu de l'objet en json, donc je l'ai exprimé en json. Le langage utilisé est Java)

//object1
{
  "id":1,
 "nom": "original",
 "description": "même",
}

//object2
{
  "id":2,
 "name": "est un clone",
 "description": "même",
}

Comparez les propriétés de ʻObject1 et ʻObject2 de ce modèle, Je veux le suivant qui ne produit que les propriétés qui diffèrent.

 //以下のような例で比較できて,
CompareHelper.diff(Object1,Object2);

 //出力はこんな感じにしてくれるやつ
{
  "id":2,
 "name": "est un clone",
}

Site de référence

Voici ce que je voulais faire quand je l'ai cherché moi-même. https://ocs.hatenadiary.org/entry/20101204/1291396815

ObjectUtils.equal(aPropValue, bPropValue) Était obsolète, donc ObjectUtils.notEqual(aPropValue, bPropValue) J'aimerais que vous vous référiez à l'exemple d'utilisation.

Est conforme au site de référence et utilise la bibliothèque.

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import lombok.Data;

public class CompareHelper {

    public static <T> List<Difference> diff(T a, T b) {
        BeanWrapper aWrap = new BeanWrapperImpl(a);
        PropertyDescriptor[] pds = aWrap.getPropertyDescriptors();
        List<String> propertyNames = new ArrayList<String>();
        for (PropertyDescriptor pd : pds) {
            if (aWrap.isReadableProperty(pd.getName())) {
                propertyNames.add(pd.getName());
            }
        }

        BeanWrapper bWrap = new BeanWrapperImpl(b);
        List<Difference> differences = new ArrayList<Difference>();

        for (String propertyName : propertyNames) {
            Object aPropValue = aWrap.getPropertyValue(propertyName);
            Object bPropValue = bWrap.getPropertyValue(propertyName);
            if (ObjectUtils.notEqual(aPropValue, bPropValue)) {
                Difference d = new Difference();
                d.setPropertyName(propertyName);
                d.setLeft(aPropValue);
                d.setRight(bPropValue);
                differences.add(d);
            }
        }

        return differences;
    }

    @Data
    public static class Difference {
        private String propertyName;
        private Object left;
        private Object right;
    }
}

Quand utiliser

Lors de son utilisation, il ressemble à ce qui suit Vous pouvez comparer les mêmes objets et récupérer les noms de propriétés et leurs valeurs qui sont différents.

Je me demande si la scène utilisée en tant qu'utilisateur Spring ressemble à ceci. .. ..


 //比較するオブジェクトの例として,よくあるユーザエンティティを使用してみました
@Entity
public class User implements Cloneable {

 // Le clone de l'objet # est protégé et ne peut pas être appelé par défaut.
 // Remplacer la méthode de clonage
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String description;
}


 //上記のようなユーザのエンティティ同士を比較します.
public void main(){
 //オリジナルのオブジェクトは,こんな感じで取得していたとする.
 // Le nom d'origine est "Avant de renommer".
    User original = userService.findByUserName("original");

 //オリジナルのクローンを作成
    User clone = original.clone();    

 //オリジナルの名前に変更があった
 original.setName ("renommé");

 //オリジナルとクローンを比較
    List<Difference> diffList = CompareHelper.diff(clone, original);
    for (Difference diff : diffList) {
        System.out.println( diff.getPropertyName() + " : " + diff.getLeft() + " -> " + 
     diff.getRight() );
    }    
}

 // La sortie ressemble à ceci
 //> nom: avant de renommer-> renommé

Sentiments divers

Explication de la méthode de comparaison elle-même lorsqu'elle est examinée à la légère (Explication des addictions courantes telles que l'utilisation de ʻequals, ==et===`) Je n'ai pas pu me rendre à l'endroit que je voulais faire parce qu'un site pour le faire est sorti.

Existe-t-il un utilitaire qui peut faire des choses similaires dans d'autres langages, frameworks et bibliothèques en premier lieu?

Cette fois j'ai étudié en me basant sur le site de référence, Pour faire la différence entre les propriétés sans utiliser la bibliothèque et en gardant les spécifications de base du langage ... N'y a-t-il pas d'autre choix que de créer la méthode diff pour chaque classe seule?

Si vous le savez, faites-le moi savoir!

Recommended Posts

Java Méthode à usage général qui récupère uniquement les différences entre les propriétés des objets de la même classe
[Java] Wrapper qui exécute la méthode privée d'un objet depuis l'extérieur de la classe
Sortie de la différence entre chaque champ de deux objets en Java
[Java] Différences entre les variables d'instance et les variables de classe
Différence entre Java, C # et JavaScript (comment trouver le degré d'obésité)
Incrémenté du troisième argument de la méthode iterate de la classe Stream ajoutée depuis Java9
[Java] Où est la classe d'implémentation de l'annotation qui existe dans BeanValidation?
[Java] Gestion des Java Beans dans la chaîne de méthodes
A propos de l'ordre de description des propriétés système Java
Importer des fichiers de la même hiérarchie en Java
Classe StringConverter à usage général qui utilise des génériques dans Java8
Première touche de la classe Files (ou Java 8)
Parcourir les objets de classe dans Kotlin (au lieu de Java class name.class)
Récapitulez les éléments supplémentaires de la classe Optional dans Java 9
Remplacez seulement une partie de l'hôte URL par java