Output the difference between each field of two objects in Java


public interface MiscUtil {
    //Object before change to o1 and object after change to o2(Same class as o1)Specify
    //If new, specify null for o1
    default String getCompareFieldValuesString(Object o1, Object o2, List<Class<?>> skipFieldClasses, List<String> skipFieldNames) {
        try {
            Set<String> skipFieldNamesSet = new HashSet<>(skipFieldNames);
            Class<?> clazz = o1 != null ? o1.getClass() : o2.getClass();
            StringBuffer sb = new StringBuffer();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                Class<?> fieldClass = field.getType();
                if (isAssignable(fieldClass, skipFieldClasses)) {
                String fieldName = field.getName();
                if (skipFieldNamesSet.contains(fieldName)) {
                Object o1Value = o1 != null ? field.get(o1) : null;
                Object o2Value = field.get(o2);
                if (isAssignable(fieldClass, Arrays.asList(String.class)) && isEmpty((String) o1Value) && isEmpty((String) o2Value)) {
                    continue; //String null and empty string are equivalent(Proposal original)
                if (isAssignable(fieldClass, Arrays.asList(LocalDateTime.class, LocalTime.class))) {
                    fieldName = fieldName.replaceAll("Raw$", ""); //LocalDateTime ・ Do not output "Raw" at the end of the LocalTime field name(Proposal original)
                String o1ValueString = getValueString(o1Value);
                String o2ValueString = getValueString(o2Value);
                if (!equals(o1ValueString, o2ValueString)) {
                    if (sb.length() > 0) {
                        sb.append(", ");
                    if (o1 != null) {
                        sb.append(String.format("%s:%s->%s", fieldName, o1ValueString, o2ValueString));
                    } else {
                        sb.append(String.format("%s:%s", fieldName, o2ValueString));
            return sb.toString();
        } catch (Throwable throwable) {
            throw new RuntimeException(throwable);

    default boolean isAssignable(Class<?> fromClass, List<Class<?>> toClasses) {
        for (Class<?> toClass : toClasses) {
            if (toClass.isAssignableFrom(fromClass)) {
                return true;
        return false;

    default boolean isEmpty(String s) {
        return StringUtils.isEmpty(s); //Null and empty string are treated as Empty

    default boolean equals(Object o1, Object o2) {
        if (o1 != null) {
            return o1.equals(o2);
        return false; //False even if both are null(Should it be true?)

    default String getValueString(Object o) {
        if (o == null) {
            return "null";
        if (o instanceof String) {
            String s = (String) o;
            return String.format("\"%s\"", escape(s));
        if (o instanceof LocalDateTime) {
            return toStr(plus9Hours((LocalDateTime) o)); //Add 9 hours(Proposal original)
        if (o instanceof LocalTime) {
            return toStr(plus9Hours((LocalTime) o)); //Add 9 hours(Proposal original)
        if (o instanceof LocalDate) {
            return toStr((LocalDate) o);
        return String.format("%s", o.toString());

    default String escape(String s) {
        return s.replaceAll("\n", "\\\\n"); //Line breaks\\Convert to n

    static final String DATE_FORMAT = "yyyy/MM/dd(E)";
    static final String TIME_FORMAT = "HH:mm";
    static final String DATETIME_FORMAT = DATE_FORMAT + " " + TIME_FORMAT;

    default String toStr(LocalDateTime datetime) {
        return datetime != null ? DateTimeFormatter.ofPattern(DATETIME_FORMAT, Locale.JAPANESE).format(datetime) : null;

    default String toStr(LocalDate date) {
        return date != null ? DateTimeFormatter.ofPattern(DATE_FORMAT, Locale.JAPANESE).format(date) : null;

    default String toStr(LocalTime time) {
        return time != null ? DateTimeFormatter.ofPattern(TIME_FORMAT, Locale.JAPANESE).format(time) : null;

    default LocalDateTime plus9Hours(LocalDateTime localDateTime) {
        return localDateTime != null ? localDateTime.plusHours(9) : null;

    default LocalTime plus9Hours(LocalTime localTime) {
        return localTime != null ? localTime.plusHours(9) : null;

Recommended Posts

Output the difference between each field of two objects in Java
Get the result of POST in Java
Difference between final and Immutable in Java
Easily measure the size of Java Objects
Output of the book "Introduction to Java"
The story of writing Java in Emacs
Difference between int and Integer in Java
[Rails] Difference in behavior between delegate and has_many-through in the case of one-to-one-to-many
The story of acquiring Java Silver in two months from completely inexperienced.
Understand the difference between int and Integer and BigInteger in java and float and double
[Java] Understand the difference between List and Set
The story of low-level string comparison in Java
[Java] Handling of JavaBeans in the method chain
The story of making ordinary Othello in Java
About the idea of anonymous classes in Java
[Android] Easily calculate the difference between two dates
The story of learning Java in the first programming
Measure the size of a folder in Java
Difference between next () and nextLine () in Java Scanner
Feel the passage of time even in Java
[Java] Something is displayed as "-0.0" in the output
Import files of the same hierarchy in Java
Summarize the life cycle of Java objects to be aware of in Android development
Make the JSON of the snake case correspond to the field of the camel case in Java (JVM)
Format of the log output by Tomcat itself in Tomcat 8
About the difference between classes and instances in Ruby
Browse class objects in Kotlin (instead of Java class name.class)
Calculate the difference between numbers in a Ruby array
[Java] Difference between static final and final in member variables
[JAVA] What is the difference between interface and abstract? ?? ??
[Java] Get the file in the jar regardless of the environment
The objects in the List were references, right? Confirmation of
Java General-purpose method that retrieves only the differences between the properties of objects of the same class
Understand in 3 minutes! A very rough explanation of the difference between session and cookie
Change the storage quality of JPEG images in Java
What is the difference between Java EE and Jakarta EE?
Output in multiples of 3
Summarize the additional elements of the Optional class in Java 9
What is the difference between the responsibilities of the domain layer and the application layer in the onion architecture [DDD]
How to manage the difference in each environment with yml without increasing the number of RAILS_ENV
Was done in the base year of the Java calendar week
[Note] Java Output of the sum of odd and even elements
A quick explanation of the five types of static in Java
Difference between Java and JavaScript (how to find the average)
About the difference between "(double quotation)" and "single quotation" in Ruby
Activate Excel file A1 cell of each sheet in Java
Count the number of digits after the decimal point in Java
[Ruby] About the difference between 2 dots and 3 dots of range object.
[Java] Difference between assignment of basic type variable and assignment of reference type variable
[Java] Check the difference between orElse and orElseGet with IntStream
Think about the differences between functions and methods (in Java)
How to derive the last day of the month in Java
[Java] Difference between Stack Overflow Error and Out Of Memory Error
Is short-circuit evaluation really fast? Difference between && and & in Java
[Java] Difference between == and equals
Implementation of gzip in java
Implementation of tri-tree in Java
Comparison of version strings (Java implementation) when you want to branch the process between two versions
Consider implementing a method that returns the difference between two Lists
This is the Excel output in Java! "JXLS" official document translation
[Java] Get the dates of the past Monday and Sunday in order