|
|
|
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
|
|
|
|
/* |
|
|
|
|
* Copyright 2002-2022 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. |
|
|
|
@ -73,11 +73,13 @@ public final class CollectionFactory {
@@ -73,11 +73,13 @@ public final class CollectionFactory {
|
|
|
|
|
private static final Set<Class<?>> approximableMapTypes = Set.of( |
|
|
|
|
// Standard map interfaces
|
|
|
|
|
Map.class, |
|
|
|
|
MultiValueMap.class, |
|
|
|
|
SortedMap.class, |
|
|
|
|
NavigableMap.class, |
|
|
|
|
// Common concrete map classes
|
|
|
|
|
HashMap.class, |
|
|
|
|
LinkedHashMap.class, |
|
|
|
|
LinkedMultiValueMap.class, |
|
|
|
|
TreeMap.class, |
|
|
|
|
EnumMap.class); |
|
|
|
|
|
|
|
|
@ -93,7 +95,9 @@ public final class CollectionFactory {
@@ -93,7 +95,9 @@ public final class CollectionFactory {
|
|
|
|
|
* @return {@code true} if the type is <em>approximable</em> |
|
|
|
|
*/ |
|
|
|
|
public static boolean isApproximableCollectionType(@Nullable Class<?> collectionType) { |
|
|
|
|
return (collectionType != null && approximableCollectionTypes.contains(collectionType)); |
|
|
|
|
return (collectionType != null && (approximableCollectionTypes.contains(collectionType) || |
|
|
|
|
collectionType.getName().equals("java.util.SequencedSet") || |
|
|
|
|
collectionType.getName().equals("java.util.SequencedCollection"))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -118,13 +122,7 @@ public final class CollectionFactory {
@@ -118,13 +122,7 @@ public final class CollectionFactory {
|
|
|
|
|
*/ |
|
|
|
|
@SuppressWarnings({"rawtypes", "unchecked"}) |
|
|
|
|
public static <E> Collection<E> createApproximateCollection(@Nullable Object collection, int capacity) { |
|
|
|
|
if (collection instanceof LinkedList) { |
|
|
|
|
return new LinkedList<>(); |
|
|
|
|
} |
|
|
|
|
else if (collection instanceof List) { |
|
|
|
|
return new ArrayList<>(capacity); |
|
|
|
|
} |
|
|
|
|
else if (collection instanceof EnumSet enumSet) { |
|
|
|
|
if (collection instanceof EnumSet enumSet) { |
|
|
|
|
Collection<E> copy = EnumSet.copyOf(enumSet); |
|
|
|
|
copy.clear(); |
|
|
|
|
return copy; |
|
|
|
@ -132,6 +130,12 @@ public final class CollectionFactory {
@@ -132,6 +130,12 @@ public final class CollectionFactory {
|
|
|
|
|
else if (collection instanceof SortedSet sortedSet) { |
|
|
|
|
return new TreeSet<>(sortedSet.comparator()); |
|
|
|
|
} |
|
|
|
|
else if (collection instanceof LinkedList) { |
|
|
|
|
return new LinkedList<>(); |
|
|
|
|
} |
|
|
|
|
else if (collection instanceof List) { |
|
|
|
|
return new ArrayList<>(capacity); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
return new LinkedHashSet<>(capacity); |
|
|
|
|
} |
|
|
|
@ -178,7 +182,9 @@ public final class CollectionFactory {
@@ -178,7 +182,9 @@ public final class CollectionFactory {
|
|
|
|
|
public static <E> Collection<E> createCollection(Class<?> collectionType, @Nullable Class<?> elementType, int capacity) { |
|
|
|
|
Assert.notNull(collectionType, "Collection type must not be null"); |
|
|
|
|
if (LinkedHashSet.class == collectionType || HashSet.class == collectionType || |
|
|
|
|
Set.class == collectionType || Collection.class == collectionType) { |
|
|
|
|
Set.class == collectionType || Collection.class == collectionType || |
|
|
|
|
collectionType.getName().equals("java.util.SequencedSet") || |
|
|
|
|
collectionType.getName().equals("java.util.SequencedCollection")) { |
|
|
|
|
return new LinkedHashSet<>(capacity); |
|
|
|
|
} |
|
|
|
|
else if (ArrayList.class == collectionType || List.class == collectionType) { |
|
|
|
@ -187,8 +193,8 @@ public final class CollectionFactory {
@@ -187,8 +193,8 @@ public final class CollectionFactory {
|
|
|
|
|
else if (LinkedList.class == collectionType) { |
|
|
|
|
return new LinkedList<>(); |
|
|
|
|
} |
|
|
|
|
else if (TreeSet.class == collectionType || NavigableSet.class == collectionType |
|
|
|
|
|| SortedSet.class == collectionType) { |
|
|
|
|
else if (TreeSet.class == collectionType || NavigableSet.class == collectionType || |
|
|
|
|
SortedSet.class == collectionType) { |
|
|
|
|
return new TreeSet<>(); |
|
|
|
|
} |
|
|
|
|
else if (EnumSet.class.isAssignableFrom(collectionType)) { |
|
|
|
@ -216,7 +222,8 @@ public final class CollectionFactory {
@@ -216,7 +222,8 @@ public final class CollectionFactory {
|
|
|
|
|
* @return {@code true} if the type is <em>approximable</em> |
|
|
|
|
*/ |
|
|
|
|
public static boolean isApproximableMapType(@Nullable Class<?> mapType) { |
|
|
|
|
return (mapType != null && approximableMapTypes.contains(mapType)); |
|
|
|
|
return (mapType != null && (approximableMapTypes.contains(mapType) || |
|
|
|
|
mapType.getName().equals("java.util.SequencedMap"))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -246,6 +253,9 @@ public final class CollectionFactory {
@@ -246,6 +253,9 @@ public final class CollectionFactory {
|
|
|
|
|
else if (map instanceof SortedMap sortedMap) { |
|
|
|
|
return new TreeMap<>(sortedMap.comparator()); |
|
|
|
|
} |
|
|
|
|
else if (map instanceof MultiValueMap) { |
|
|
|
|
return new LinkedMultiValueMap(capacity); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
return new LinkedHashMap<>(capacity); |
|
|
|
|
} |
|
|
|
@ -292,26 +302,22 @@ public final class CollectionFactory {
@@ -292,26 +302,22 @@ public final class CollectionFactory {
|
|
|
|
|
@SuppressWarnings({"rawtypes", "unchecked"}) |
|
|
|
|
public static <K, V> Map<K, V> createMap(Class<?> mapType, @Nullable Class<?> keyType, int capacity) { |
|
|
|
|
Assert.notNull(mapType, "Map type must not be null"); |
|
|
|
|
if (mapType.isInterface()) { |
|
|
|
|
if (Map.class == mapType) { |
|
|
|
|
return new LinkedHashMap<>(capacity); |
|
|
|
|
} |
|
|
|
|
else if (SortedMap.class == mapType || NavigableMap.class == mapType) { |
|
|
|
|
return new TreeMap<>(); |
|
|
|
|
} |
|
|
|
|
else if (MultiValueMap.class == mapType) { |
|
|
|
|
return new LinkedMultiValueMap(); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
throw new IllegalArgumentException("Unsupported Map interface: " + mapType.getName()); |
|
|
|
|
} |
|
|
|
|
if (LinkedHashMap.class == mapType || HashMap.class == mapType || Map.class == mapType || |
|
|
|
|
mapType.getName().equals("java.util.SequencedMap")) { |
|
|
|
|
return new LinkedHashMap<>(capacity); |
|
|
|
|
} |
|
|
|
|
else if (LinkedMultiValueMap.class == mapType || MultiValueMap.class == mapType) { |
|
|
|
|
return new LinkedMultiValueMap(); |
|
|
|
|
} |
|
|
|
|
else if (TreeMap.class == mapType || SortedMap.class == mapType || NavigableMap.class == mapType) { |
|
|
|
|
return new TreeMap<>(); |
|
|
|
|
} |
|
|
|
|
else if (EnumMap.class == mapType) { |
|
|
|
|
Assert.notNull(keyType, "Cannot create EnumMap for unknown key type"); |
|
|
|
|
return new EnumMap(asEnumType(keyType)); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
if (!Map.class.isAssignableFrom(mapType)) { |
|
|
|
|
if (mapType.isInterface() || !Map.class.isAssignableFrom(mapType)) { |
|
|
|
|
throw new IllegalArgumentException("Unsupported Map type: " + mapType.getName()); |
|
|
|
|
} |
|
|
|
|
try { |
|
|
|
|