Prefer ArrayList for Collection when source is an array

Closes gh-28048
This commit is contained in:
Juergen Hoeller 2023-07-05 20:23:17 +02:00
parent 47e631d5ff
commit 0c8d3e70cf
2 changed files with 13 additions and 3 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.core.convert.support; package org.springframework.core.convert.support;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
@ -69,7 +70,7 @@ final class ArrayToCollectionConverter implements ConditionalGenericConverter {
int length = Array.getLength(source); int length = Array.getLength(source);
TypeDescriptor elementDesc = targetType.getElementTypeDescriptor(); TypeDescriptor elementDesc = targetType.getElementTypeDescriptor();
Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), Collection<Object> target = createCollection(targetType.getType(),
(elementDesc != null ? elementDesc.getType() : null), length); (elementDesc != null ? elementDesc.getType() : null), length);
if (elementDesc == null) { if (elementDesc == null) {
@ -89,4 +90,13 @@ final class ArrayToCollectionConverter implements ConditionalGenericConverter {
return target; return target;
} }
private Collection<Object> createCollection(Class<?> targetType, @Nullable Class<?> elementType, int length) {
if (targetType.isInterface() && targetType.isAssignableFrom(ArrayList.class)) {
// Source is an array -> prefer ArrayList for Collection and SequencedCollection.
// CollectionFactory.createCollection traditionally prefers LinkedHashSet instead.
return new ArrayList<>(length);
}
return CollectionFactory.createCollection(targetType, elementType, length);
}
} }

View File

@ -343,7 +343,7 @@ class DefaultConversionServiceTests {
@Test @Test
void convertArrayToCollectionInterface() { void convertArrayToCollectionInterface() {
Collection<?> result = conversionService.convert(new String[] {"1", "2", "3"}, Collection.class); Collection<?> result = conversionService.convert(new String[] {"1", "2", "3"}, Collection.class);
assertThat(result).isEqualTo(Set.of("1", "2", "3")); assertThat(result).isEqualTo(List.of("1", "2", "3"));
} }
@Test @Test