It's like String.equals ("A", "B"), there are comparisons between objects, but `How do you compare the properties in an object and extract the parts that differ? `` I looked it up.
What I want to do is when there is an object like the one below (I thought it would be easy to explain the contents of the object in json, so I expressed it in json. The language used is Java)
//object1
{
"id":1,
"name": "Original",
"description": "same",
}
//object2
{
"id":2,
"name": "is a clone",
"description": "same",
}
Compare the properties of ʻObject1 and ʻObject2
in this pattern,
I want the following one that outputs only the properties that differ.
//以下のような例で比較できて,
CompareHelper.diff(Object1,Object2);
//出力はこんな感じにしてくれるやつ
{
"id":2,
"name": "is a clone",
}
Here is what I wanted to do when I looked it up myself. https://ocs.hatenadiary.org/entry/20101204/1291396815
ObjectUtils.equal(aPropValue, bPropValue)
Was deprecated, so
ObjectUtils.notEqual(aPropValue, bPropValue)
I'd like you to refer to the usage example.
Is as per the reference site and uses the library.
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;
}
}
When using it, it looks like the following You can compare the same objects and retrieve the different property names and their values.
I wonder if the scene used as a Spring user looks like this. .. ..
//比較するオブジェクトの例として,よくあるユーザエンティティを使用してみました
@Entity
public class User implements Cloneable {
// Object # clone is protected and cannot be called by default.
// Override the clone method
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(){
//オリジナルのオブジェクトは,こんな感じで取得していたとする.
// The original name is "Before renaming".
User original = userService.findByUserName("original");
//オリジナルのクローンを作成
User clone = original.clone();
//オリジナルの名前に変更があった
original.setName ("renamed");
//オリジナルとクローンを比較
List<Difference> diffList = CompareHelper.diff(clone, original);
for (Difference diff : diffList) {
System.out.println( diff.getPropertyName() + " : " + diff.getLeft() + " -> " +
diff.getRight() );
}
}
// The output looks like this
//> name: Before renaming-> Renamed
Explanation of the comparison method itself when examined lightly
(Explanation of common addictive points such as using ʻequals,
== and
=== `)
I couldn't get to the place I wanted to do because a site to do it came out.
Is there a utility that can do similar things in other languages, frameworks, and libraries in the first place?
This time I studied based on the reference site,
To get the difference between properties without using the library and keeping the basic language specifications ...
Is there no choice but to create the diff
method for each class on its own?
If you know, please let me know!
Recommended Posts