-
Notifications
You must be signed in to change notification settings - Fork 38.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve CollectionFactory to allow for single statement collection creation #28025
Comments
Based on the requirements you've stated here and in #28094 (comment), I've come up with the following simple prototype. @SafeVarargs
public static <E, C extends Collection<E>> C collectionOf(Supplier<C> collectionFactory, E... elements) {
Assert.notNull(collectionFactory, "'collectionFactory' must not be null");
C collection = collectionFactory.get();
Collections.addAll(collection, elements);
return collection;
} With the following test cases passing. @Test
void collectionOfWorksCorrectly() {
List<String> list = collectionOf(ArrayList::new, "foo", "bar");
assertThat(list).isInstanceOf(ArrayList.class).containsExactly("foo", "bar");
Set<Integer> set = collectionOf(HashSet::new, 4, 3, 2, 1);
assertThat(set).isInstanceOf(HashSet.class).containsExactlyInAnyOrder(1, 2, 3, 4);
Set<Integer> orderedSet = collectionOf(LinkedHashSet::new, 4, 2, 3, 1);
assertThat(orderedSet).isInstanceOf(LinkedHashSet.class).containsExactlyInAnyOrder(4, 2, 3, 1);
SortedSet<Integer> sortedSet = collectionOf(TreeSet::new, 4, 3, 2, 1);
assertThat(sortedSet).isInstanceOf(TreeSet.class).containsExactly(1, 2, 3, 4);
} @snicoll, is that what you had in mind? Please note that the tests had to be written that way (with the created collection stored in a local variable), since there were compiler issues with AssertJ's |
Not quite. The single statement works obviously but not the type inference.
This is linked to AOT where we have a collection instance we'd like to write back. Taking the type of the collection is what I had in mind but I haven't dig enough. Phil also may have made that irrelevant with the latest update of code generation. |
We could call that inference algorithm based on the instance and get back the nearest type and use that for code generation. So I take it back, looks like that would work. Thanks. |
Are you saying that the proposed If so, I'd be happy to push it to However, there's no rush on my side. So if it's not OK as-is, we can iterate over alternate solutions for 6.0 M5. |
This commit serves as a proof of concept for factory methods in CollectionFactory that allow a collection to be created as a one-liner using var-args. createCollection(Class<C>, Class<E>, E...) internally delegates to createCollection(Class<?>, Class<?>, int) to create the collection based on the supplied collectionType and populates the collection from the var-args. The elementType is only required when creating an EnumSet and could therefore conceivably be omitted if we do not want to support EnumSet for this collection factory method. collectionOf(Supplier<C>, E...) creates the collection using the supplied collectionFactory and populates the collection from the var-args. See spring-projectsgh-28025
@snicoll, I've pushed a proof of concept to the following branch. I think the new Thanks! |
This is no longer needed as the AOT use cases became irrelevant. |
Right now
CollectionFactory
allows to create a collection type, trying to find the most suitable implementation based on an concrete instance.We have some use cases in AOT where we'd like to be able to streamline the creation of a collection in a single statement. We've tried something along those lines:
Unfortunately the indirection with the collector can easily confuse the compiler. A more direct use where the
collectionFactory
would be provided with a bunch of elements could be nice.The text was updated successfully, but these errors were encountered: