我想创建一个遍历存储ArrayList<U>
的任何集合的方法 - 让我们调用该集合T
;例如,它可以是LinkedList
,ArrayList
或任何其他Collection
; U
- 是另一种需要记忆的类型;我想要创建的方法应该返回相同的集合T
,但它应该存储LinkedList<U>
。
&#34;错误&#34;期望的声明:
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;
}
我仔细阅读documentation,但我找不到实现目标的方式。
答案 0 :(得分:3)
我的建议:
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;
}
请注意,您必须传递Supplier
才能使该方法能够创建所需类型的Collection
实例。
用法:
ArrayList<ArrayList<String>> in = new ArrayList<> ();
in.add (new ArrayList<String> ());
in.get (0).add ("abc");
ArrayList<LinkedList<String>> out = rewrap (in, ArrayList::new);
编辑:您应该注意,此方法不要求输出外部Collection
的类型与输入外部Collection
的类型相同。
例如,如果您在上面的示例中传递ArrayList<ArrayList<String>>
供应商而不是HashSet<LinkedList<String>>
,则可以传递HashSet::new
输入并获得ArrayList::new
输出。
答案 1 :(得分:1)
这将符合您的请求,但不严格强制使用返回集合类型来匹配输入类型:
public <U> List<LinkedList<U>> rewrap(Collection<ArrayList<U>> arrayList) {
T linkedList = ...
// do some stuff here
return linkedList;
}
我不认为通用接口有一种方法可以在编译时强制执行返回的列表与进入的Collection具有相同的实现。
另请注意,您无法重复使用收集集合或致电new T<...>()
。您必须使用反射或其他方法参数。
答案 2 :(得分:1)
public static void main(String[] args) {
// create inner list
ArrayList<String> innerList = new ArrayList<>();
innerList.add("test string 1"); innerList.add("test string 2");
// add it to outer List twice because why not
ArrayList<ArrayList<String>> outerList = new ArrayList<>();
outerList.add(innerList); outerList.add(innerList);
// rewrap it
ArrayList<LinkedList<String>> rewrapped = rewrap(outerList);
System.out.println("rewrapped.");
}
public static <T, C extends Collection<LinkedList<T>>> C rewrap (Collection<ArrayList<T>> in) {
Collection<LinkedList<T>> out = null;
try {
out = (in.getClass().newInstance());
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
C myC = (C) out;
for (ArrayList<T> list : in) {
myC.add (new LinkedList<T> (list));
}
return myC;
}
当然,您需要一些更好的异常处理,但此示例代码的工作方式与我预期的相同。