I want to create a method that traverses through any collection that stores ArrayList<U>
- let's call that collection T
; for example, it can be LinkedList
, ArrayList
or any other Collection
; U
- is another type which is needed to be memorized; and the method I want to create should return the same collection T
but it should store LinkedList<U>
instead.
"Wrong" desired declaration:
public <T extends Collection, U> T<LinkedList<U>> rewrap (T<ArrayList<U>> arrayList) {
T<LinkedList<U>> linkedList = new T<LinkedList<U>>();
// do some stuff here
return linkedList;
}
I carefully read the documentation but I didn't find the way how I can achieve my goal.
My suggestion:
public static <T, C extends Collection<LinkedList<T>>> C rewrap (Collection<ArrayList<T>> in, Supplier<C> collectionFactory) {
C out = collectionFactory.get ();
for (ArrayList<T> list : in) {
out.add (new LinkedList<T> (list));
}
return out;
}
Note that you must pass a Supplier
in order for the method to be able to create an instance of the Collection
of the desired type.
Usage:
ArrayList<ArrayList<String>> in = new ArrayList<> ();
in.add (new ArrayList<String> ());
in.get (0).add ("abc");
ArrayList<LinkedList<String>> out = rewrap (in, ArrayList::new);
EDIT: You should note that this method doesn't require that the type of the output outer Collection
is the same as the type of the input outer Collection
.
For example, you can pass an ArrayList<ArrayList<String>>
input and get a HashSet<LinkedList<String>>
output if you pass a HashSet::new
supplier instead of ArrayList::new
in the above example.