This works as long as you have POJOs with their own getters and setters. The method updates obj with non-null values from update. It calls setParameter() on obj with the return value of getParameter() on update:

public void merge(Object obj, Object update){
    if(!obj.getClass().isAssignableFrom(update.getClass())){
        return;
    }

    Method[] methods = obj.getClass().getMethods();

    for(Method fromMethod: methods){
        if(fromMethod.getDeclaringClass().equals(obj.getClass())
                && fromMethod.getName().startsWith("get")){

            String fromName = fromMethod.getName();
            String toName = fromName.replace("get", "set");

            try {
                Method toMetod = obj.getClass().getMethod(toName, fromMethod.getReturnType());
                Object value = fromMethod.invoke(update, (Object[])null);
                if(value != null){
                    toMetod.invoke(obj, value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }
    }
}
Answer from Alex Martín Jiménez on Stack Overflow
🌐
Medium
medium.com › @joantolos › merging-two-objects-in-java-5bc43cd8ab74
Merging two objects in Java. Using reflection and a bit of recursion… | by Joan Tolos | Medium
February 13, 2019 - The idea is to use reflection to iterate the fields of the local object and compare them with it’s equivalent on the remote one. Then apply the rules to decide which field value will prevail. I have created a simple project on GitHub with the solution and one example: kata-merge-object
Top answer
1 of 11
31

This works as long as you have POJOs with their own getters and setters. The method updates obj with non-null values from update. It calls setParameter() on obj with the return value of getParameter() on update:

public void merge(Object obj, Object update){
    if(!obj.getClass().isAssignableFrom(update.getClass())){
        return;
    }

    Method[] methods = obj.getClass().getMethods();

    for(Method fromMethod: methods){
        if(fromMethod.getDeclaringClass().equals(obj.getClass())
                && fromMethod.getName().startsWith("get")){

            String fromName = fromMethod.getName();
            String toName = fromName.replace("get", "set");

            try {
                Method toMetod = obj.getClass().getMethod(toName, fromMethod.getReturnType());
                Object value = fromMethod.invoke(update, (Object[])null);
                if(value != null){
                    toMetod.invoke(obj, value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }
    }
}
2 of 11
23

I am using Spring Framework. I was facing the same issue on a project.
To solve it i used the class BeanUtils and the above method,

public static void copyProperties(Object source, Object target)

This is an example,

public class Model1 {
    private String propertyA;
    private String propertyB;

    public Model1() {
        this.propertyA = "";
        this.propertyB = "";
    }

    public String getPropertyA() {
        return this.propertyA;
    }

    public void setPropertyA(String propertyA) {
        this.propertyA = propertyA;
    }

    public String getPropertyB() {
        return this.propertyB;
    }

    public void setPropertyB(String propertyB) {
        this.propertyB = propertyB;
    }
}

public class Model2 {
    private String propertyA;

    public Model2() {
        this.propertyA = "";
    }

    public String getPropertyA() {
        return this.propertyA;
    }

    public void setPropertyA(String propertyA) {
        this.propertyA = propertyA;
    }
}

public class JustATest {

    public void makeATest() {
        // Initalize one model per class.
        Model1 model1 = new Model1();
        model1.setPropertyA("1a");
        model1.setPropertyB("1b");

        Model2 model2 = new Model2();
        model2.setPropertyA("2a");

        // Merge properties using BeanUtils class.
        BeanUtils.copyProperties(model2, model1);

        // The output.
        System.out.println("Model1.propertyA:" + model1.getPropertyA(); //=> 2a
        System.out.println("Model1.propertyB:" + model1.getPropertyB(); //=> 1b
    }
}
Top answer
1 of 3
1

Edited to address the issue of 4 specific fields allowed to mismatch.

@Hans-Martin Mosner is right that the remaining fields form a unique key. It's best to address this with the database, but it sounds like you can't in your circumstances. In this case, Option 1 seems to be the superior choice.

Option 3 is obviously undesirable because of its O(N^2) complexity, but why not Option 2? The main reason is that once we add an object to a set, we cannot retrieve it without iterating through the collection at O(N). So there's no way to "merge" two equal objects in O(1) (the main reason for preferring 2 to 3), other than simply replacing the existing object. This doesn't sound like what you wanted. You can use a modified form of Option 2 by using a HashMap<CustomObject, CustomObject>, but this is basically Option 1 except you're not keeping a list.

So what does this key look like?

If you want the key to be a CustomObject (for either Option 1 or modified Option 2), then we'll need to override hashCode() to use all and only the fields that we care about (e.g. like this). This is an especially nice option if you've already overridden equals(obj).

If you want a String key, then you can concatenate all the field values that we care about (including a separator to prevent values from one field flowing into another). E.g. assuming that field1, ... fieldN have a suitable toString():

String getKey(CustomObject obj) {
   return obj.getField1() + "|" + ... + "|" obj.getFieldN();
}

Original answer assuming any 4 fields were allowed to mismatch.

As ugly as it seems, I think the most viable algorithm proposed is Option 3*. Here's why.

The Problem of Option 1

Let's suppose we have our list and we're going through elements one by one. We encounter the problem on the first element. How do we even know what the "concatenated string of all similar attributes" is for this element? We have nothing to compare against. In order to determine this, we need to scan through the rest of the elements and compare them to this particular element. It's up to you if we break once we find a match, or look for a better candidate / all candidates.

Okay, on to the next element. If it was marked as a duplicate already, then we might be able to skip this. Otherwise, then we are in exactly the same situation as before: we have to run through each of the subsequent elements looking for a potential match.

(You see where this is going, don't you?)

The Problem of Option 2

So you've decided to stick our objects in a Set. Great, we've got 2 popular choices: a HashSet and a TreeSet.

If we choose a HashSet, then we need to define a hashcode, particularly one such that equal objects have the same hashcode. Because of our fuzzy version of equality, defining a suitable hashcode is going to be really difficult. Given what I know of the problem, the only consistent hash seems to be a constant. (You may be able to do better, but it's not an easy task.) Practically this means that set.contains(myObj) will have linear lookup time, so we're back to O(N^2) for overall complexity.

If we choose a TreeSet, then we need to define an ordering. Again, good luck with finding one that works with our fuzzy equality. Worst case for this will also give us linear lookup time.

Aside

The problem of detecting duplicates is hard. For example, what potential duplicates do we have among this data?

A = { a: 1, b: 1 }, B = { a: 1, b: 2 }, C = { a: 2, b: 1 }, D = { a: 2, b: 2 }

Pairwise, A and D are each similar to both B and C. But B and C are not similar to each other; nor are A and D similar.

*Technically, option 3 takes N(N+1)/2 steps and not N^2, but I'm assuming that you are referring to the big-O.

2 of 3
4

This sort of problem is much easier solved if you know the meaning of those records and the process by which duplicates happen. Look at the actual fields and decide which ones should be "keys" and which ones should be "values", then you have basically solved it (you need to decide on a proper database representation but that's an implementation issue).

So if you already know the 4 fields that are variable, all others constitute the primary key. You could either simply concatenate them to form a hash key, or build a hierarchical map structure, or let a relational database engine figure out the details. All of these might be viable solutions depending on your problem details which you omitted from the question.

🌐
Baeldung
baeldung.com › home › java › core java › merging java.util.properties objects
Merging java.util.Properties Objects | Baeldung
July 25, 2025 - Internally, this calls the put() method from the Hashtable class but ensures the objects are String values. Note, it is strongly discouraged to use the put() method directly as it allows the caller to insert entries whose keys or values are not Strings. Now let’s look at how we can merge two or more properties objects using iteration:
Top answer
1 of 5
4

Just tested using reflection. The desired output is

merged person:Person{name=John, lastName=Snow}     



public static void testReflection() {
        Person p1 = new Person("John", null);
        Person p2 = new Person(null, "Snow");
        Person merged = (Person) mergePersons(p1, p2);
        System.out.println("merged person:" + merged);
}

public static Object mergePersons(Object obj1, Object obj2) throws Exception {
    Field[] allFields = obj1.getClass().getDeclaredFields();
    for (Field field : allFields) {
        if (Modifier.isPublic(field.getModifiers()) && field.isAccessible() && field.get(obj1) == null && field.get(obj2) != null) {
            field.set(obj1, field.get(obj2));
        }
    }
    return obj1;
}

mergePersons accepts two Objects.

Then it go through all fields and validate if the first object has a null value. If yes, then it verify if the second object is not nulled.

If this is true it assigns the value to the first Object.

Providing this solution you only access public data. If you want to access private data aswell, you need to remove the Modifier verification and set if accessible before like:

public static Object mergePersons(Object obj1, Object obj2) throws Exception {
    Field[] allFields = obj1.getClass().getDeclaredFields();
    for (Field field : allFields) {

        if (!field.isAccessible() && Modifier.isPrivate(field.getModifiers())) 
            field.setAccessible(true);
        if (field.get(obj1) == null && field.get(obj2) != null) {
            field.set(obj1, field.get(obj2));
        }
    }
    return obj1;
}
2 of 5
3

This is a quick (and presumptuous) approach that is basically the same as using reflection on the fields but instead uses:

  1. Groovy's built-in getProperties() method on java.lang.Object, which provides us with a Map of its property names and values
  2. Groovy's default Map constructor, which allows use to create instances of an Object given a Map of properties.

Given these two features, you can describe each object you want to merge as a Map of their properties, strip out the null-valued entries, combine the Maps together (and remove the pesky 'class' entry which is readonly), and use the merged Map to construct your merged instance.

class Person {
    String first, last, middle
}

def p1 = new Person(first: 'bob')
def p2 = new Person(last: 'barker')

Person merged = (p1.properties.findAll { k, v -> v }  // p1's non-null properties
               + p2.properties.findAll { k, v -> v }) // plus p2's non-null properties
               .findAll { k, v -> k != 'class' }      // excluding the 'class' property

assert merged.first == 'bob'
assert merged.last == 'barker'
assert merged.middle == null
🌐
GitHub
github.com › Freeongoo › java-merge-object
GitHub - Freeongoo/java-merge-object: A simple way to summarize the fields of objects · GitHub
MergeObject mergeObject = new MergeObjectImpl(); Set<String> fields = new HashSet<>(Arrays.asList("age")); mergeObject.sumNumberFields(catTo, catFrom, fields); System.out.println(catTo.getAge()); // 5
Author: Freeongoo
🌐
Baeldung
baeldung.com › home › java › java collections › combining different types of collections in java
Combining Different Types of Collections in Java | Baeldung
April 4, 2025 - To learn about the Collectors in detail, visit Guide to Java 8’s Collectors. ... List<Object> combined = Stream.of(first, second).flatMap(Collection::stream).collect(Collectors.toList()); First, we’re using Stream.of() which returns a sequential stream of two lists – first and second. We’ll then pass it to flatMap which will return the contents of a mapped stream after applying the mapping function. This method also discussed in Merging Streams in Java article.
Top answer
1 of 4
19

You're going to have to go the reflection route. I'm assuming you have a default constructor, otherwise the following won't work. Also, it needs two same types. It won't copy inherited fields, for that, you also need to add some code from here.

@SuppressWarnings("unchecked")
public static <T> T mergeObjects(T first, T second) throws IllegalAccessException, InstantiationException {
    Class<?> clazz = first.getClass();
    Field[] fields = clazz.getDeclaredFields();
    Object returnValue = clazz.newInstance();
    for (Field field : fields) {
        field.setAccessible(true);
        Object value1 = field.get(first);
        Object value2 = field.get(second);
        Object value = (value1 != null) ? value1 : value2;
        field.set(returnValue, value);
    }
    return (T) returnValue;
}

Here's an example

public static class ABC {
    private int id;
    private String name;
    private int[] numbers;

    public ABC() {
    }


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int[] getNumbers() {
        return numbers;
    }

    public void setNumbers(int[] numbers) {
        this.numbers = numbers;
    }
}

public static void main(String[] args) throws InstantiationException, IllegalAccessException {
    ABC abc = new ABC();
    abc.setId(1);
    abc.setName("Hello");
    int[] newnumbers = new int[5];
    for(int i = 0; i < newnumbers.length; i++) {
        newnumbers[i] = i;
    }
    abc.setNumbers(newnumbers);
    ABC abc2 = new ABC();
    abc2.setName("World");

    ABC abcFinal = mergeObjects(abc, abc2);
    System.out.println("Properties of ABC Final:");
    System.out.println("ID: " + abcFinal.getId());
    System.out.println("Name: " + abcFinal.getName());
    System.out.println("Numbers: " + Arrays.toString(abcFinal.getNumbers()));
}

Output:

Properties of ABC Final:
ID: 1
Name: Hello
Numbers: [0, 1, 2, 3, 4]
2 of 4
4

In case you want to create a new Object use:

public ABC mergeABC(ABC obj1, ABC obj2){
    ABC retVal = new ABC();
    retVal.name   = ((obj1.name   != null) ? obj1.name   : obj2.name   );
    retVal.id     = ((obj1.id     != null) ? obj1.id     : obj2.id     );
    retVal.salary = ((obj1.salary != null) ? obj1.salary : obj2.salary );
    retVal.status = ((obj1.status != null) ? obj1.status : obj2.status );
    return retVal;
}

If you want to "reuse" obj1 or obj2, simply use this as return value.

Find elsewhere
🌐
Coderanch
coderanch.com › t › 691517 › java › combine-objects-Streams
How can you combine two objects into one, using Streams? (Beginning Java forum at Coderanch)
March 6, 2018 - It all boils down to if it's recommended to use Streams when you have two different lists, and the objects into those lists must be combine into another one, 1:1. By 1:1, I mean that the object at index 0 in one list will have to be combined with the object at index 0 in the other list.
Top answer
1 of 5
34

Its pretty easy to do using the org.springframework.beans.BeanUtils class provided by spring. Or the Apache Commons BeanUtils library which I believe Springs version is either based on or is the same as.

public static <T> T combine2Objects(T a, T b) throws InstantiationException, IllegalAccessException {
    // would require a noargs constructor for the class, maybe you have a different way to create the result.
    T result = (T) a.getClass().newInstance();
    BeanUtils.copyProperties(a, result);
    BeanUtils.copyProperties(b, result);
    return result;
}

if you cant or dont have a noargs constructor maybe you just pass in the result

public static <T> T combine2Objects(T a, T b, T destination) {
    BeanUtils.copyProperties(a, destination);
    BeanUtils.copyProperties(b, destination);
    return destination;
}

If you dont want null properties being copied you can use something like this:

public static void nullAwareBeanCopy(Object dest, Object source) throws IllegalAccessException, InvocationTargetException {
    new BeanUtilsBean() {
        @Override
        public void copyProperty(Object dest, String name, Object value)
                throws IllegalAccessException, InvocationTargetException {
            if(value != null) {
                super.copyProperty(dest, name, value);
            }
        }
    }.copyProperties(dest, source);
}

Nested object solution

Heres a bit more robust solution. It supports nested object copying, objects 1+ level deep will no longer be copied by reference, instead Nested objects will be cloned or their properties be copied individually.

/**
 * Copies all properties from sources to destination, does not copy null values and any nested objects will attempted to be
 * either cloned or copied into the existing object. This is recursive. Should not cause any infinite recursion.
 * @param dest object to copy props into (will mutate)
 * @param sources
 * @param <T> dest
 * @return
 * @throws IllegalAccessException
 * @throws InvocationTargetException
 */
public static <T> T copyProperties(T dest, Object... sources) throws IllegalAccessException, InvocationTargetException {
    // to keep from any chance infinite recursion lets limit each object to 1 instance at a time in the stack
    final List<Object> lookingAt = new ArrayList<>();

    BeanUtilsBean recursiveBeanUtils = new BeanUtilsBean() {

        /**
         * Check if the class name is an internal one
         * @param name
         * @return
         */
        private boolean isInternal(String name) {
            return name.startsWith("java.") || name.startsWith("javax.")
                    || name.startsWith("com.sun.") || name.startsWith("javax.")
                    || name.startsWith("oracle.");
        }

        /**
         * Override to ensure that we dont end up in infinite recursion
         * @param dest
         * @param orig
         * @throws IllegalAccessException
         * @throws InvocationTargetException
         */
        @Override
        public void copyProperties(Object dest, Object orig) throws IllegalAccessException, InvocationTargetException {
            try {
                // if we have an object in our list, that means we hit some sort of recursion, stop here.
                if(lookingAt.stream().anyMatch(o->o == dest)) {
                    return; // recursion detected
                }
                lookingAt.add(dest);
                super.copyProperties(dest, orig);
            } finally {
                lookingAt.remove(dest);
            }
        }

        @Override
        public void copyProperty(Object dest, String name, Object value)
                throws IllegalAccessException, InvocationTargetException {
            // dont copy over null values
            if (value != null) {
                // attempt to check if the value is a pojo we can clone using nested calls
                if(!value.getClass().isPrimitive() && !value.getClass().isSynthetic() && !isInternal(value.getClass().getName())) {
                    try {
                        Object prop = super.getPropertyUtils().getProperty(dest, name);
                        // get current value, if its null then clone the value and set that to the value
                        if(prop == null) {
                            super.setProperty(dest, name, super.cloneBean(value));
                        } else {
                            // get the destination value and then recursively call
                            copyProperties(prop, value);
                        }
                    } catch (NoSuchMethodException e) {
                        return;
                    } catch (InstantiationException e) {
                        throw new RuntimeException("Nested property could not be cloned.", e);
                    }
                } else {
                    super.copyProperty(dest, name, value);
                }
            }
        }
    };


    for(Object source : sources) {
        recursiveBeanUtils.copyProperties(dest, source);
    }

    return dest;
}

Its kinda quick and dirty but works well. Since it does use recursion and the potential is there for infinite recursion I did place in a safety against.

2 of 5
4

The below method will ignore the serialVersionUID, iterate through all the fields and copy the non-null values from object a --> object b if they are null in b. In other words, if any field is null in b, take it from a if there its not null.

public static <T> T combine2Objects(T a, T b) throws InstantiationException,IllegalAccessException{
            T result = (T) a.getClass().newInstance();
            Object[] fields = Arrays.stream(a.getClass().getDeclaredFields()).filter(f -> !f.getName().equals("serialVersionUID")).collect(Collectors.toList()).toArray();
            for (Object fieldobj : fields) {
                Field field = (Field) fieldobj;
                field.set(result, field.get(b) != null ? field.get(b) : field.get(a));
            }
            return result;
    }
🌐
Coderanch
coderanch.com › t › 450842 › java › merging-data-values-similar-objects
merging data values of two similar objects (Java in General forum at Coderanch)
For purpose of illustration I will provide a simplified scenario is like Class custom {BigDecimal a; String b; BigDecimal c; Boolean d;} I have an instance of this class objOriginalCustom {a=10; b="Custom"; c=10.5; d=true;} Also i get another instance of the same class objUpdateCustom { a="25";b='Update"} Now what i want to do is modify the attributes of objOriginalCustom with the values of objUpdateCustom but only the ones for which i have valid values and retain the original data values if there are no replaceable values available in the objUpdteCustom (like c=10.5 and d=true) and replace a and b with values of 25 and "update" Is there a convenient way to achieve the same in java or your thoughts on the approach to follow for the same. Rgrds ... You could write a method that takes the update object, calls the getter for each property.
Top answer
1 of 1
2

Spring's spring-beans library has a org.springframework.beans.BeanUtils class that provides a copyProperties method to copy a source object instance into a target object instance. However, it only does so for the object's first level fields. Here is my solution, based on BeanUtils.copyProperties, to recursively perform the copy for every child object including collections and maps.

package my.utility;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * Created by cdebergh on 1/6/17.
 */
public class BeanUtils extends org.springframework.beans.BeanUtils {

    /**
     * Copy the not null property values of the given source bean into the target bean.
     * <p>Note: The source and target classes do not have to match or even be derived
     * from each other, as long as the properties match. Any bean properties that the
     * source bean exposes but the target bean does not will silently be ignored.
     * <p>This is just a convenience method. For more complex transfer needs,
     * consider using a full BeanWrapper.
     * @param source the source bean
     * @param target the target bean
     * @throws BeansException if the copying failed
     * @see BeanWrapper
     */
    public static void copyPropertiesNotNull(Object source, Object target) throws BeansException {
        copyPropertiesNotNull(source, target, null, (String[]) null);
    }

    private static void setAccessible(Method method) {
        if (!Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
            method.setAccessible(true);
        }
    }

    /**
     * Copy the not null property values of the given source bean into the given target bean.
     * <p>Note: The source and target classes do not have to match or even be derived
     * from each other, as long as the properties match. Any bean properties that the
     * source bean exposes but the target bean does not will silently be ignored.
     * @param source the source bean
     * @param target the target bean
     * @param editable the class (or interface) to restrict property setting to
     * @param ignoreProperties array of property names to ignore
     * @throws BeansException if the copying failed
     * @see BeanWrapper
     */
    private static void copyPropertiesNotNull(Object source, Object target, Class<?> editable, String... ignoreProperties)
            throws BeansException {

        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");

        Class<?> actualEditable = target.getClass();
        if (editable != null) {
            if (!editable.isInstance(target)) {
                throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
                        "] not assignable to Editable class [" + editable.getName() + "]");
            }
            actualEditable = editable;
        }
        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
        List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);

        for (PropertyDescriptor targetPropertyDescriptor : targetPds) {
            Method targetWriteMethod = targetPropertyDescriptor.getWriteMethod();
            if (targetWriteMethod != null
                    && (ignoreList == null || !ignoreList.contains(targetPropertyDescriptor.getName()))) {
                PropertyDescriptor sourcePropertyDescriptor =
                        getPropertyDescriptor(source.getClass(), targetPropertyDescriptor.getName());
                if (sourcePropertyDescriptor != null) {
                    Method sourceReadMethod = sourcePropertyDescriptor.getReadMethod();
                    if (sourceReadMethod != null &&
                            ClassUtils.isAssignable(
                                    targetWriteMethod.getParameterTypes()[0], sourceReadMethod.getReturnType())) {
                        try {
                            Method targetReadMethod = targetPropertyDescriptor.getReadMethod();
                            setAccessible(sourceReadMethod);
                            setAccessible(targetWriteMethod);
                            Object sourceValue = sourceReadMethod.invoke(source);

                            if (sourceValue != null && targetReadMethod != null) {
                                setAccessible(targetReadMethod);
                                Object targetValue = targetReadMethod.invoke(target);
                                if (targetValue == null) {
                                    targetWriteMethod.invoke(target, sourceValue);
                                } else if(targetValue instanceof Collection<?>) {
                                    ((Collection) targetValue).addAll((Collection) sourceValue);
                                } else if (targetValue instanceof Map<?,?>) {
                                    ((Map) targetValue).putAll((Map) sourceValue);
                                } else {
                                    copyPropertiesNotNull(sourceValue, targetValue, editable, ignoreProperties);
                                }
                            }
                        }
                        catch (Throwable ex) {
                            throw new FatalBeanException(
                                    "Could not copy property '" + targetPropertyDescriptor.getName() +
                                    "' from source to target", ex);
                        }
                    }
                }
            }
        }
    }
}
🌐
Readthedocs
java-object-diff.readthedocs.io › en › latest › merging
Merging - java-object-diff Documentation - Read the Docs
Every node in the object graph returned by the ObjectDiffer provides setter methods, which can be used to change the state of an underlying object instance, as long as it is of the same type as the compared objects. Since the requirements to a merging mechanism can vary strongly, this library doesn't try to implement every possible way and rather strives to make it as easy as possible to implement your own one.
🌐
TutorialsPoint
tutorialspoint.com › how-can-we-merge-two-json-objects-in-java
How can we merge two JSON objects in Java?
import java.util.Date; import org.json.simple.JSONObject; public class MergeJsonObjectsTest { public static void main(String[] args) { JSONObject jsonObj = new JSONObject(); // first json object jsonObj.put("Name", "Adithya"); jsonObj.put("Age", 25); jsonObj.put("Address", "Hitech City"); JSONObject jsonObj1 = new JSONObject(); // second json object jsonObj1.put("City", "Hyderabad"); jsonObj1.put("DOB", new Date(104, 3, 6)); jsonObj.putAll(jsonObj1); // merging of first and second json objects System.out.println(jsonObj); } }
🌐
CodingTechRoom
codingtechroom.com › question › merge-objects-in-java
How to Merge Two Objects in Java - CodingTechRoom
Conflicts can arise when both objects have the same key with different values. Use the `merge` method available in the `Map` interface for a straightforward approach.
🌐
AlgoMonster
algo.monster › liteproblems › 2755
2755. Deep Merge of Two Objects - In-Depth Explanation
1import java.util.*; 2 3public class DeepMergeUtil { 4 5 /** 6 * Deep merge two objects or arrays recursively 7 * @param obj1 - The target object/array to merge into 8 * @param obj2 - The source object/array to merge from 9 * @return The merged result (modifies obj1 in place) 10 */ 11 public static Object deepMerge(Object obj1, Object obj2) { 12 // If either value is not an object (including null), return the second value 13 if (!isObject(obj1) || !isObject(obj2)) { 14 return obj2; 15 } 16 17 // If one is a List and the other is not, return the second value 18 if (isArray(obj1) != isArray(obj2
🌐
Quora
quora.com › How-do-I-add-two-different-objects-into-a-single-object-in-Java-I-need-a-sample-program-for-this-concept
How do I add two different objects into a single object in Java? I need a sample program for this concept.
Answer (1 of 2): public interface Vehicle { public void typeOfVehicle(); } ///////////////////////////////////////////////////////////////////////////////////////////////// public class Car implements Vehicle { public void typeOfVehicle() { System.out.println("This is Car"); } } ////////...
Top answer
1 of 5
146

java.util.Properties implements the java.util.Map interface, and so you can just treat it as such, and use methods like putAll to add the contents of another Map.

However, if you treat it like a Map, you need to be very careful with this:

new Properties(defaultProperties);

This often catches people out, because it looks like a copy constructor, but it isn't. If you use that constructor, and then call something like keySet() (inherited from its Hashtable superclass), you'll get an empty set, because the Map methods of Properties do not take account of the default Properties object that you passed into the constructor. The defaults are only recognised if you use the methods defined in Properties itself, such as getProperty and propertyNames, among others.

So if you need to merge two Properties objects, it is safer to do this:

Properties merged = new Properties();
merged.putAll(properties1);
merged.putAll(properties2);

This will give you more predictable results, rather than arbitrarily labelling one of them as the "default" property set.

Normally, I would recommend not treating Properties as a Map, because that was (in my opinion) an implementation mistake from the early days of Java (Properties should have contained a Hashtable, not extended it - that was lazy design), but the anemic interface defined in Properties itself doesn't give us many options.

2 of 5
20

Assuming you eventually would like to read the properties from a file, I'd go for loading both files in the same properties object like:

Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("default.properties"));
properties.load(getClass().getResourceAsStream("custom.properties"));