Skip to content

Commit 612aa4c

Browse files
committed
Added tests that prove that multiple dimensional collections can be converted to multiple dimensional arrays, and multiple dimensional arrays can be converted to multiple dimension collections
1 parent a2dcc03 commit 612aa4c

File tree

3 files changed

+214
-5
lines changed

3 files changed

+214
-5
lines changed

src/main/java/com/cedarsoftware/util/convert/ArrayConversions.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,29 @@ static Object arrayToArray(Object sourceArray, Class<?> targetArrayType, Convert
5656
}
5757

5858
/**
59-
* Converts a collection to an array.
59+
* Converts a collection to an array, handling nested collections recursively.
60+
*
61+
* @param collection The source collection to convert
62+
* @param arrayType The target array type
63+
* @param converter The converter instance for type conversions
64+
* @return An array of the specified type containing the collection elements
6065
*/
6166
static Object collectionToArray(Collection<?> collection, Class<?> arrayType, Converter converter) {
6267
Class<?> componentType = arrayType.getComponentType();
6368
Object array = Array.newInstance(componentType, collection.size());
6469
int index = 0;
70+
6571
for (Object item : collection) {
66-
if (item == null || componentType.isAssignableFrom(item.getClass())) {
67-
Array.set(array, index++, item);
72+
Object convertedValue;
73+
if (item instanceof Collection && componentType.isArray()) {
74+
// Handle nested collections recursively
75+
convertedValue = collectionToArray((Collection<?>) item, componentType, converter);
76+
} else if (item == null || componentType.isAssignableFrom(item.getClass())) {
77+
convertedValue = item;
6878
} else {
69-
Array.set(array, index++, converter.convert(item, componentType));
79+
convertedValue = converter.convert(item, componentType);
7080
}
81+
Array.set(array, index++, convertedValue);
7182
}
7283
return array;
7384
}

src/test/java/com/cedarsoftware/util/TestUniqueIdGenerator.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.cedarsoftware.util;
22

3+
import java.time.Instant;
34
import java.util.Date;
45
import java.util.HashSet;
56
import java.util.LinkedHashSet;
@@ -8,12 +9,13 @@
89
import java.util.concurrent.ExecutorService;
910
import java.util.concurrent.Executors;
1011

11-
import org.junit.jupiter.api.Disabled;
1212
import org.junit.jupiter.api.Test;
1313
import org.junit.jupiter.api.condition.EnabledIf;
1414

1515
import static com.cedarsoftware.util.UniqueIdGenerator.getDate;
1616
import static com.cedarsoftware.util.UniqueIdGenerator.getDate19;
17+
import static com.cedarsoftware.util.UniqueIdGenerator.getInstant;
18+
import static com.cedarsoftware.util.UniqueIdGenerator.getInstant19;
1719
import static com.cedarsoftware.util.UniqueIdGenerator.getUniqueId;
1820
import static com.cedarsoftware.util.UniqueIdGenerator.getUniqueId19;
1921
import static java.lang.Math.abs;
@@ -65,6 +67,18 @@ void testIDtoDate()
6567
assert abs(date.getTime() - currentTimeMillis()) < 2;
6668
}
6769

70+
@Test
71+
void testIDtoInstant()
72+
{
73+
long id = getUniqueId();
74+
Instant instant = getInstant(id);
75+
assert abs(instant.toEpochMilli() - currentTimeMillis()) < 2;
76+
77+
id = getUniqueId19();
78+
instant = getInstant19(id);
79+
assert abs(instant.toEpochMilli() - currentTimeMillis()) < 2;
80+
}
81+
6882
@Test
6983
void testUniqueIdGeneration()
7084
{

src/test/java/com/cedarsoftware/util/convert/ConverterArrayCollectionTest.java

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
2929
import static org.junit.jupiter.api.Assertions.assertEquals;
3030
import static org.junit.jupiter.api.Assertions.assertNotNull;
31+
import static org.junit.jupiter.api.Assertions.assertNull;
3132
import static org.junit.jupiter.api.Assertions.assertThrows;
3233
import static org.junit.jupiter.api.Assertions.assertTrue;
3334

@@ -667,4 +668,187 @@ void testStringArrayToCharArrayThrows() {
667668
assertThrows(IllegalArgumentException.class, conversion, "Converting String[] to char[] should throw IllegalArgumentException if any Strings have more than 1 character");
668669
}
669670
}
671+
672+
@Test
673+
public void testMultiDimensionalCollectionToArray() {
674+
// Create a nested List structure: List<List<Integer>>
675+
List<List<Integer>> nested = Arrays.asList(
676+
Arrays.asList(1, 2, 3),
677+
Arrays.asList(4, 5, 6),
678+
Arrays.asList(7, 8, 9)
679+
);
680+
681+
// Convert to int[][]
682+
int[][] result = converter.convert(nested, int[][].class);
683+
684+
// Verify the conversion
685+
assertEquals(3, result.length);
686+
assertEquals(3, result[0].length);
687+
assertEquals(1, result[0][0]);
688+
assertEquals(5, result[1][1]);
689+
assertEquals(9, result[2][2]);
690+
691+
// Test with mixed collection types (List<Set<String>>)
692+
List<Set<String>> mixedNested = Arrays.asList(
693+
new HashSet<>(Arrays.asList("a", "b", "c")),
694+
new HashSet<>(Arrays.asList("d", "e", "f")),
695+
new HashSet<>(Arrays.asList("g", "h", "i"))
696+
);
697+
698+
String[][] stringResult = converter.convert(mixedNested, String[][].class);
699+
assertEquals(3, stringResult.length);
700+
assertEquals(3, stringResult[0].length);
701+
702+
// Sort the arrays to ensure consistent comparison since Sets don't maintain order
703+
for (String[] arr : stringResult) {
704+
Arrays.sort(arr);
705+
}
706+
707+
assertArrayEquals(new String[]{"a", "b", "c"}, stringResult[0]);
708+
assertArrayEquals(new String[]{"d", "e", "f"}, stringResult[1]);
709+
assertArrayEquals(new String[]{"g", "h", "i"}, stringResult[2]);
710+
}
711+
712+
@Test
713+
public void testMultiDimensionalArrayToArray() {
714+
// Test conversion from int[][] to long[][]
715+
int[][] source = {
716+
{1, 2, 3},
717+
{4, 5, 6},
718+
{7, 8, 9}
719+
};
720+
721+
long[][] result = converter.convert(source, long[][].class);
722+
723+
assertEquals(3, result.length);
724+
assertEquals(3, result[0].length);
725+
assertEquals(1L, result[0][0]);
726+
assertEquals(5L, result[1][1]);
727+
assertEquals(9L, result[2][2]);
728+
729+
// Test conversion from Integer[][] to String[][]
730+
Integer[][] sourceIntegers = {
731+
{1, 2, 3},
732+
{4, 5, 6},
733+
{7, 8, 9}
734+
};
735+
736+
String[][] stringResult = converter.convert(sourceIntegers, String[][].class);
737+
738+
assertEquals(3, stringResult.length);
739+
assertEquals(3, stringResult[0].length);
740+
assertEquals("1", stringResult[0][0]);
741+
assertEquals("5", stringResult[1][1]);
742+
assertEquals("9", stringResult[2][2]);
743+
}
744+
745+
@Test
746+
public void testMultiDimensionalArrayToCollection() {
747+
// Create a source array
748+
String[][] source = {
749+
{"a", "b", "c"},
750+
{"d", "e", "f"},
751+
{"g", "h", "i"}
752+
};
753+
754+
// Convert to List<List<String>>
755+
List<List<String>> result = (List<List<String>>) converter.convert(source, List.class);
756+
757+
assertEquals(3, result.size());
758+
assertEquals(3, result.get(0).size());
759+
assertEquals("a", result.get(0).get(0));
760+
assertEquals("e", result.get(1).get(1));
761+
assertEquals("i", result.get(2).get(2));
762+
763+
// Test with primitive array to List<List<Long>>
764+
int[][] primitiveSource = {
765+
{1, 2, 3},
766+
{4, 5, 6},
767+
{7, 8, 9}
768+
};
769+
770+
List<List<Integer>> intResult = (List<List<Integer>>) converter.convert(primitiveSource, List.class);
771+
772+
assertEquals(3, intResult.size());
773+
assertEquals(3, intResult.get(0).size());
774+
assertEquals(Integer.valueOf(1), intResult.get(0).get(0));
775+
assertEquals(Integer.valueOf(5), intResult.get(1).get(1));
776+
assertEquals(Integer.valueOf(9), intResult.get(2).get(2));
777+
}
778+
779+
@Test
780+
public void testThreeDimensionalConversions() {
781+
// Test 3D array conversion
782+
int[][][] source = {
783+
{{1, 2}, {3, 4}},
784+
{{5, 6}, {7, 8}}
785+
};
786+
787+
// Convert to long[][][]
788+
long[][][] result = converter.convert(source, long[][][].class);
789+
790+
assertEquals(2, result.length);
791+
assertEquals(2, result[0].length);
792+
assertEquals(2, result[0][0].length);
793+
assertEquals(1L, result[0][0][0]);
794+
assertEquals(8L, result[1][1][1]);
795+
796+
// Create 3D collection
797+
List<List<List<Integer>>> nested3D = Arrays.asList(
798+
Arrays.asList(
799+
Arrays.asList(1, 2),
800+
Arrays.asList(3, 4)
801+
),
802+
Arrays.asList(
803+
Arrays.asList(5, 6),
804+
Arrays.asList(7, 8)
805+
)
806+
);
807+
808+
// Convert to 3D array
809+
int[][][] arrayResult = converter.convert(nested3D, int[][][].class);
810+
811+
assertEquals(2, arrayResult.length);
812+
assertEquals(2, arrayResult[0].length);
813+
assertEquals(2, arrayResult[0][0].length);
814+
assertEquals(1, arrayResult[0][0][0]);
815+
assertEquals(8, arrayResult[1][1][1]);
816+
}
817+
818+
@Test
819+
public void testNullHandling() {
820+
List<List<String>> nestedWithNulls = Arrays.asList(
821+
Arrays.asList("a", null, "c"),
822+
null,
823+
Arrays.asList("d", "e", "f")
824+
);
825+
826+
String[][] result = converter.convert(nestedWithNulls, String[][].class);
827+
828+
assertEquals(3, result.length);
829+
assertEquals("a", result[0][0]);
830+
assertNull(result[0][1]);
831+
assertEquals("c", result[0][2]);
832+
assertNull(result[1]);
833+
assertEquals("f", result[2][2]);
834+
}
835+
836+
@Test
837+
public void testMixedDimensionalCollections() {
838+
// Test converting a collection where some elements are single dimension
839+
// and others are multi-dimensional
840+
List<Object> mixedDimensions = Arrays.asList(
841+
Arrays.asList(1, 2, 3),
842+
4,
843+
Arrays.asList(5, 6, 7)
844+
);
845+
846+
Object[] result = converter.convert(mixedDimensions, Object[].class);
847+
848+
assertTrue(result[0] instanceof List);
849+
assertEquals(3, ((List<?>) result[0]).size());
850+
assertEquals(4, result[1]);
851+
assertTrue(result[2] instanceof List);
852+
assertEquals(3, ((List<?>) result[2]).size());
853+
}
670854
}

0 commit comments

Comments
 (0)