Java Allzweckmethode, die nur die Unterschiede zwischen den Eigenschaften von Objekten derselben Klasse abruft

Einführung

Es ist wie bei String.equals ("A", "B"), es gibt Vergleiche zwischen Objekten, aber `Wie vergleicht man Eigenschaften in einem Objekt und extrahiert die Teile, die sich unterscheiden? `` Ich habe es nachgeschlagen.

Was ich tun möchte, ist, wenn es ein Objekt wie das folgende gibt (Ich dachte, es wäre einfach, den Inhalt des Objekts in json zu erklären, also habe ich es in json ausgedrückt. Die verwendete Sprache ist Java.)

//object1
{
  "id":1,
 "Name": "Original",
 "description": "same",
}

//object2
{
  "id":2,
 "name": "ist ein Klon",
 "description": "same",
}

Vergleichen Sie die Eigenschaften von "Objekt1" und "Objekt2" dieses Musters miteinander. Ich möchte die folgende, die nur die Eigenschaften ausgibt, die sich unterscheiden.

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

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

Referenzseite

Folgendes wollte ich tun, als ich es selbst nachgeschlagen habe. https://ocs.hatenadiary.org/entry/20101204/1291396815

ObjectUtils.equal(aPropValue, bPropValue) War also veraltet ObjectUtils.notEqual(aPropValue, bPropValue) Ich möchte, dass Sie sich auf das Verwendungsbeispiel beziehen.

Entspricht der Referenzseite und verwendet die Bibliothek.

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;
    }
}

Wann zu verwenden

Wenn Sie es verwenden, sieht es wie folgt aus Sie können dieselben Objekte vergleichen und die unterschiedlichen Eigenschaftsnamen und deren Werte abrufen.

Ich frage mich, ob die als Spring-Benutzer verwendete Szene so aussieht. .. ..


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

 // Objekt # Klon ist geschützt und kann nicht standardmäßig aufgerufen werden.
 // Überschreibe die Klonmethode
    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(){
 //オリジナルのオブジェクトは,こんな感じで取得していたとする.
 // Der ursprüngliche Name lautet "Vor dem Umbenennen".
    User original = userService.findByUserName("original");

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

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

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

 // Die Ausgabe sieht so aus
 //> name: Vor dem Umbenennen-> Umbenannt

Verschiedene Gefühle

Erläuterung der Vergleichsmethode selbst bei leichter Betrachtung (Erklärung allgemeiner Suchtpunkte wie die Verwendung von "gleich", "==" und "===") Ich konnte nicht an den Ort gelangen, den ich tun wollte, weil eine Website dafür herauskam.

Gibt es ein Dienstprogramm, das ähnliche Aufgaben in anderen Sprachen, Frameworks und Bibliotheken ausführen kann?

Dieses Mal habe ich anhand der Referenzseite studiert. Um den Unterschied zwischen Eigenschaften zu ermitteln, ohne die Bibliothek zu verwenden und die grundlegenden Sprachspezifikationen beizubehalten ... Gibt es keine andere Wahl, als die "diff" -Methode für jede Klasse für sich zu erstellen?

Wenn Sie es wissen, lassen Sie es mich bitte wissen!

Recommended Posts

Java Allzweckmethode, die nur die Unterschiede zwischen den Eigenschaften von Objekten derselben Klasse abruft
[Java] Wrapper, der die private Methode eines Objekts von außerhalb der Klasse ausführt
Geben Sie die Differenz zwischen jedem Feld zweier Objekte in Java aus
[Java] Unterschiede zwischen Instanzvariablen und Klassenvariablen
Unterschied zwischen Java, C # und JavaScript (wie man den Grad der Fettleibigkeit findet)
Inkrementiert durch das dritte Argument der iterierten Methode der aus Java9 hinzugefügten Stream-Klasse
[Java] Wo befindet sich die Implementierungsklasse der Annotation, die in BeanValidation vorhanden ist?
[Java] Behandlung von Java Beans in der Methodenkette
Informationen zur Beschreibungsreihenfolge der Java-Systemeigenschaften
Importieren Sie Dateien derselben Hierarchie in Java
Allzweck-StringConverter-Klasse, die Generika in Java8 verwendet
Erster Touch der Files-Klasse (oder Java 8)
Durchsuchen Sie Klassenobjekte in Kotlin (anstelle der Java-Klasse name.class).
Fassen Sie die zusätzlichen Elemente der optionalen Klasse in Java 9 zusammen
Ersetzen Sie nur einen Teil des URL-Hosts durch Java