From 0c8d3e70cfca2e2d80e27e76a755924f6d5e9942 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 5 Jul 2023 20:23:17 +0200 Subject: [PATCH] Prefer ArrayList for Collection when source is an array Closes gh-28048 --- .../support/ArrayToCollectionConverter.java | 14 ++++++++++++-- .../converter/DefaultConversionServiceTests.java | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionConverter.java index ea96d762c6..7a9c76239d 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionConverter.java @@ -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"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.core.convert.support; import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Set; @@ -69,7 +70,7 @@ final class ArrayToCollectionConverter implements ConditionalGenericConverter { int length = Array.getLength(source); TypeDescriptor elementDesc = targetType.getElementTypeDescriptor(); - Collection target = CollectionFactory.createCollection(targetType.getType(), + Collection target = createCollection(targetType.getType(), (elementDesc != null ? elementDesc.getType() : null), length); if (elementDesc == null) { @@ -89,4 +90,13 @@ final class ArrayToCollectionConverter implements ConditionalGenericConverter { return target; } + private Collection 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); + } + } diff --git a/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java b/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java index 32f112af52..fba1806bea 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java @@ -343,7 +343,7 @@ class DefaultConversionServiceTests { @Test void convertArrayToCollectionInterface() { 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