Groovy Deep Copy Objects

Posted 10/26/2018 2:33 PM by Corey Klass

There is no built-in functionality to perform a deep-copy of a Groovy object. Below is a convenience class that will perform a deep copy of an object.

import org.grails.web.json.JSONArray
import org.grails.web.json.JSONObject

class ObjectUtility {



    /**
     * Duplicates an object
     * @param object
     * @return
     */
    static Object duplicate(Object object) {
        def duplicateObject = null

        if (object instanceof JSONObject) {
            duplicateObject = ObjectUtility.duplicateJSONObject(object)

        } else if (object instanceof JSONArray) {
            duplicateObject = ObjectUtility.duplicateJSONArray(object)

        } else if (object instanceof Map) {
            duplicateObject = ObjectUtility.duplicateMap(object as Map<Object, Object>)

        } else if (object instanceof List) {
            duplicateObject = ObjectUtility.duplicateList(object as List<Object>)

        } else if (object instanceof Collection) {
            duplicateObject = ObjectUtility.duplicateCollection(object as Collection<Object>)

        } else if (object instanceof Set) {
            duplicateObject = ObjectUtility.duplicateSet(object as Set<Object>)

        } else {
            duplicateObject = object.getClass().newInstance(object)
        }

        return duplicateObject
    }



    /**
     * Duplicates a Map
     * @param map
     */
    private static Map<Object, Object> duplicateMap(Map<Object, Object> map) {
        def duplicateMap = (map.getClass().newInstance() as Map)

        map.each { Object key, Object value ->
            duplicateMap[key] = ObjectUtility.duplicate(value)
        }

        return duplicateMap
    }




    /**
     * Duplicates a JSONObject
     * @param map
     */
    private static JSONObject duplicateJSONObject(JSONObject jsonObject) {
        def duplicateObject = (jsonObject.getClass().newInstance() as JSONObject)

        jsonObject.each { Object key, Object value ->
            duplicateObject[key] = ObjectUtility.duplicate(value)
        }

        return duplicateObject
    }



    /**
     * Duplicates a List
     * @param list
     * @return
     */
    private static List<Object> duplicateList(List<Object> list) {
        def duplicateList = (list.getClass().newInstance() as List)

        list.each { Object indexItem ->
            duplicateList.push(ObjectUtility.duplicate(indexItem))
        }

        return duplicateList
    }




    /**
     * Duplicates a JSONArray
     * @param list
     * @return
     */
    private static JSONArray duplicateJSONArray(JSONArray array) {
        def duplicateArray = (array.getClass().newInstance() as JSONArray)

        array.each {Object indexItem ->
            duplicateArray.push(ObjectUtility.duplicate(indexItem))
        }

        return duplicateArray
    }




    /**
     * Duplicates a Collection
     * @param collection
     * @return
     */
    private static Collection<Object> duplicateCollection(Collection<Object> collection) {
        def duplicateCollection = (collection.getClass().newInstance() as Collection)

        collection.each { Object indexItem ->
            duplicateCollection.add(ObjectUtility.duplicate(indexItem))
        }

        return duplicateCollection
    }



    /**
     * Duplicates a Set
     * @param set
     * @return
     */
    private static Set<Object> duplicateSet(Set<Object> set) {
        def duplicateSet = (set.getClass().newInstance() as Set)

        set.each { Object indexItem ->
            duplicateSet.add(ObjectUtility.duplicate(set))
        }

        return duplicateSet
    }



}