두 객체를 "차별"할 수있는 Java 라이브러리가 있습니까?
Unix 프로그램 diff와 유사한 Java 유틸리티 라이브러리가 있지만 Objects 용입니까? 동일한 유형의 두 개체를 비교하고 그 차이를 나타내는 데이터 구조를 생성 할 수있는 무언가를 찾고 있습니다 (그리고 인스턴스 변수의 차이를 재귀 적으로 비교할 수 있음). 난 하지 텍스트 DIFF의 자바 구현을 찾고. 리플렉션을 사용하여이 작업을 수행하는 방법에 대한 도움말 도 찾고 있지 않습니다 .
내가 유지하고있는 애플리케이션은 디자인 선택이 좋지 않고 다시 작성해야하는이 기능의 취약한 구현을 가지고 있지만, 기성품을 사용할 수 있다면 더 좋을 것입니다.
내가 찾고있는 종류의 예는 다음과 같습니다.
SomeClass a = new SomeClass();
SomeClass b = new SomeClass();
a.setProp1("A");
a.setProp2("X");
b.setProp1("B");
b.setProp2("X");
DiffDataStructure diff = OffTheShelfUtility.diff(a, b); // magical recursive comparison happens here
비교 후 유틸리티는 "prop1"이 두 개체간에 다르고 "prop2"가 동일하다고 알려줍니다. DiffDataStructure가 트리가되는 것이 가장 자연스러운 일이라고 생각하지만 코드가 신뢰할 수 있다면 까다 롭지는 않을 것입니다.
조금 늦었을 수도 있지만, 저도 당신과 같은 상황에 있었고 결국 당신의 사용 사례에 맞는 저만의 라이브러리를 만들었습니다. 내가 직접 해결책을 찾아야했기 때문에 다른 사람들의 노력을 아끼기 위해 Github에 공개하기로 결정했습니다. 여기에서 찾을 수 있습니다 : https://github.com/SQiShER/java-object-diff
--- 편집 ---
다음은 OP 코드를 기반으로 한 약간의 사용 예입니다.
SomeClass a = new SomeClass();
SomeClass b = new SomeClass();
a.setProp1("A");
a.setProp2("X");
b.setProp1("B");
b.setProp2("X");
DiffNode diff = ObjectDifferBuilder.buildDefault().compare(a, b);
assert diff.hasChanges();
assert diff.childCount() == 1;
assert diff.getChild('prop1').getState() == DiffNode.State.CHANGED;
http://javers.org 는 필요한 것을 정확히 수행하는 라이브러리입니다 : Diff 객체를 반환하는 compare (Object leftGraph, Object rightGraph)와 같은 메소드가 있습니다. Diff에는 변경 목록 (ReferenceChange, ValueChange, PropertyChange)이 포함됩니다.
given:
DummyUser user = dummyUser("id").withSex(FEMALE).build();
DummyUser user2 = dummyUser("id").withSex(MALE).build();
Javers javers = JaversTestBuilder.newInstance()
when:
Diff diff = javers.compare(user, user2)
then:
diff.changes.size() == 1
ValueChange change = diff.changes[0]
change.leftValue == FEMALE
change.rightValue == MALE
그래프의주기를 처리 할 수 있습니다.
또한 모든 그래프 개체의 스냅 샷을 얻을 수 있습니다. Javers에는 스냅 샷에 대한 JSON 직렬 변환기 및 역 직렬 변환기가 있으며 데이터베이스에 쉽게 저장할 수 있도록 변경합니다. 이 라이브러리를 사용하면 감사를위한 모듈을 쉽게 구현할 수 있습니다.
예, java-util 라이브러리에는 두 개의 Java Object Graph를 비교하는 GraphComparator 클래스가 있습니다. 차이를 델타 목록으로 반환합니다. GraphComparator를 사용하면 델타도 병합 (적용) 할 수 있습니다. 이 코드는 JDK에만 종속되며 다른 라이브러리에는 없습니다.
모든 Javers 라이브러리는 Java 7 만 지원합니다. Java 6 프로젝트에 사용하기를 원했기 때문에 소스를 가져 와서 Java 6에서 작동하는 방식을 변경했습니다. 아래는 github 코드입니다. .
https://github.com/sand3sh/javers-forJava6
Jar 링크 : https://github.com/sand3sh/javers-forJava6/blob/master/build/javers-forjava6.jar
Java 7 지원 '<>'고유 캐스트 변환 만 Java 6 지원으로 변경했습니다. 모든 사용자 지정 개체 비교에서 작동하는 불필요한 코드를 거의 언급하지 않았기 때문에 모든 기능이 작동한다고 보장하지는 않습니다.
이 코드를 사용하는 위치에 따라 유용하거나 문제가 될 수 있습니다. 이 코드를 테스트했습니다.
/**
* @param firstInstance
* @param secondInstance
*/
protected static void findMatchingValues(SomeClass firstInstance,
SomeClass secondInstance) {
try {
Class firstClass = firstInstance.getClass();
Method[] firstClassMethodsArr = firstClass.getMethods();
Class secondClass = firstInstance.getClass();
Method[] secondClassMethodsArr = secondClass.getMethods();
for (int i = 0; i < firstClassMethodsArr.length; i++) {
Method firstClassMethod = firstClassMethodsArr[i];
// target getter methods.
if(firstClassMethod.getName().startsWith("get")
&& ((firstClassMethod.getParameterTypes()).length == 0)
&& (!(firstClassMethod.getName().equals("getClass")))
){
Object firstValue;
firstValue = firstClassMethod.invoke(firstInstance, null);
logger.info(" Value "+firstValue+" Method "+firstClassMethod.getName());
for (int j = 0; j < secondClassMethodsArr.length; j++) {
Method secondClassMethod = secondClassMethodsArr[j];
if(secondClassMethod.getName().equals(firstClassMethod.getName())){
Object secondValue = secondClassMethod.invoke(secondInstance, null);
if(firstValue.equals(secondValue)){
logger.info(" Values do match! ");
}
}
}
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
You could also take a look at the solution from Apache. Most projects already have it on their classpath since its part of commons-lang.
Check difference for specific field(s):
http://commons.apache.org/proper/commons-lang/javadocs/api-3.9/org/apache/commons/lang3/builder/DiffBuilder.html
Check difference by using reflection:
http://commons.apache.org/proper/commons-lang/javadocs/api-3.9/org/apache/commons/lang3/builder/ReflectionDiffBuilder.html
A simpler approach to quickly tell you if two objects are different would be is to use the apache commons library
BeanComparator lastNameComparator = new BeanComparator("lname");
logger.info(" Match "+bc.compare(firstInstance, secondInstance));
참고URL : https://stackoverflow.com/questions/8001400/is-there-a-java-library-that-can-diff-two-objects
'Nice programing' 카테고리의 다른 글
Visual Studio에서 "코드 최적화"옵션은 실제로 어떤 역할을합니까? (0) | 2020.10.27 |
---|---|
십진수 유형의 PDO :: PARAM? (0) | 2020.10.27 |
Java 8 용 Tomcat 8 Maven 플러그인 (0) | 2020.10.27 |
Visual Studio 2015- "분석기"참조는 무엇을 의미합니까? (0) | 2020.10.27 |
.NET 세계에 대한 Maven 대안 또는 포트가 있습니까? (0) | 2020.10.27 |