Very often one needs a quick collection of values to be able to iterate over it. Instead of manually creating the instance, adding items or doing the well known constructor-initialization that creates a set out of a list out of an array (Set<String> mySet = new HashSet<String>(Arrays.AsList("a", "b", "c"))
) I wanted to create a function that should do the job for me.
Beside the Fact, that I want to provide the generic parameter <S>
to use for the collection-class, i also want to provide the generic parameter <T>
- the actual type of the Collection
.
So, my first approach was the following:
public static <T extends Collection<S>, S> T initializeCollection(Class<T> concreteClass, S... objects) {
T result;
try {
result = concreteClass.newInstance();
for (S s : objects) {
result.add(s);
}
return result;
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
This works quite well and could be used like:
LinkedList<String> myList = StaticHelper.initializeCollection(LinkedList.class, "a", "b");
or
HashSet<Integer> mySet = StaticHelper.initializeCollection(HashSet.class, 1,2,3,4,5);
from what I tested by now this works as expected. The only problem is that the validator states, that theres an unsave type conversion going on. Using the Example of the Set, the validator says
Type safety: The expression of type HashSet needs unchecked conversion to conform to HashSet<Integer>
When I look closer at the return value the IDE is stating for my function it looks like this:
<HashSet, Integer> HashSet my.namespace.helper.CollectionHelper.initializeCollection(Class<HashSet> concreteClass, Integer... objects)
Therefore the validator ofc thinks, that he has to do a unsave cast from HashSet
to HashSet<Integer>
.
But in my opinion, the return value of the function is T
, which is pretty much defined as Collection<S>
- and not as Collection
.
Now i'm wondering if:
Sidenode: Even if a good alternative has been posted (which i am already using) i'm quite interested in the solution to this problem.
public static <T extends Collection<S>, S> T<S> initializeCollection ...
or using
... initializeCollection(HashSet<Integer>.class,...
is obviously invalid syntax, but basically would look like whats required.
Not really a direct answer but you could make it simpler with:
@SafeVarargs
public static <T extends Collection<S>, S> T initializeCollection(T collection, S... objects) {
Collections.addAll(collection, objects);
return collection;
}
And call it with:
HashSet<Integer> mySet = initializeCollection(new HashSet<>(), 1, 2, 3, 4, 5);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With