From c3d35bf11025970eec19895109077967527a65bc Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Thu, 30 Nov 2023 20:18:30 -0600 Subject: [PATCH] Add byte[] and ArrayList to more efficient version of deep copy / copy constructor --- .../qqq/backend/core/model/data/QRecord.java | 7 +++++- .../backend/core/model/data/QRecordTest.java | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java index 1bcf60b6..4457b401 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/data/QRecord.java @@ -158,10 +158,15 @@ public class QRecord implements Serializable ////////////////////////////////////////////////////////////////////////// // not sure from where/how java.sql.Date objects are getting in here... // ////////////////////////////////////////////////////////////////////////// - if(value == null || value instanceof String || value instanceof Number || value instanceof Boolean || value instanceof Temporal || value instanceof Date) + if(value == null || value instanceof String || value instanceof Number || value instanceof Boolean || value instanceof Temporal || value instanceof Date || value instanceof byte[]) { clone.put(entry.getKey(), entry.getValue()); } + else if(entry.getValue() instanceof ArrayList arrayList) + { + ArrayList cloneList = new ArrayList<>(arrayList); + clone.put(entry.getKey(), (V) cloneList); + } else if(entry.getValue() instanceof Serializable serializableValue) { LOG.info("Non-primitive serializable value in QRecord - calling SerializationUtils.clone...", logPair("key", entry.getKey()), logPair("type", value.getClass())); diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordTest.java index fffd70b9..8fc66dea 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordTest.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/data/QRecordTest.java @@ -23,7 +23,9 @@ package com.kingsrook.qqq.backend.core.model.data; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.kingsrook.qqq.backend.core.BaseTest; import com.kingsrook.qqq.backend.core.model.statusmessages.BadInputStatusMessage; @@ -31,7 +33,9 @@ import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder; import org.junit.jupiter.api.Test; import static com.kingsrook.qqq.backend.core.model.data.QRecord.BACKEND_DETAILS_TYPE_HEAVY_FIELD_LENGTHS; import static com.kingsrook.qqq.backend.core.model.data.QRecord.BACKEND_DETAILS_TYPE_JSON_SOURCE_OBJECT; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -140,6 +144,25 @@ class QRecordTest extends BaseTest nullWarnings.setWarnings(null); assertNull(new QRecord(nullWarnings).getWarnings()); + QRecord byteArrayValue = new QRecord().withValue("myBytes", new byte[] { 65, 66, 67, 68 }); + assertArrayEquals(new byte[] { 65, 66, 67, 68 }, new QRecord(byteArrayValue).getValueByteArray("myBytes")); + + ArrayList originalArrayList = new ArrayList<>(List.of(1, 2, 3)); + QRecord recordWithArrayListValue = new QRecord().withValue("myList", originalArrayList); + QRecord cloneWithArrayListValue = new QRecord(recordWithArrayListValue); + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // the clone list and original list should be equals (have contents that are equals), but not be the same (reference) // + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + assertEquals(List.of(1, 2, 3), cloneWithArrayListValue.getValue("myList")); + assertNotSame(originalArrayList, cloneWithArrayListValue.getValue("myList")); + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // make sure a change to the original list doesn't change the cloned list (as it was cloned deeply) // + ////////////////////////////////////////////////////////////////////////////////////////////////////// + originalArrayList.add(4); + assertNotEquals(originalArrayList, cloneWithArrayListValue.getValue("myList")); + QRecord emptyRecord = new QRecord(); QRecord emptyClone = new QRecord(emptyRecord); assertNull(emptyClone.getTableName());