java - 如何返回具有不同元素类型的相同通用集合类型?
问题描述
我有一个方法,它将集合的元素映射到其他对象并返回包含映射元素的集合。我希望返回的 Collection 与输入 Collection 具有相同的 Collection 类型,但具有不同的元素类型。我的方法看起来像这样:
<E extends OriginalElement, T extends TargetElement,
C extends Collection<E>, R extends C<T>> R map(C elementsToMap) {
// snip
}
显然这部分R extends C<T>
不起作用。
如何将返回类型指定为Collection
与 Type相同的子类C
,但使用元素类型T
而不是E
?
解决方案
你不能,我不认为,因为例如ArrayList<String>
和ArrayList<Integer>
本质上是不相关的类型。
另外,当您说“相同的通用集合类型”时,您的意思是:
- "如果我给你一些 ArrayList 的子类,你会给我一个 java.util.ArrayList 的实例"; 或者
- “如果我给你一个ArrayList 的特定子类,你会给我一个与 ArrayList 相同的特定子类的实例”?
这不仅很难,因为通常您不知道如何实例化任意子类,您可能无法创建这样的实例,例如,如果输入是一个IntegerArrayList (extends ArrayList<Integer>)
,并且您想将元素映射到字符串。因此,虽然您可以java.util.ArrayList<String>
在这种情况下返回 a,但您无法获得通用解决方案,因为您需要了解“在这种特定情况下要实例化哪种类型”。
我将做出一个未量化的断言,即少数集合类型可以处理大多数情况。因此,为这些特定类型提供重载:
</* type variables */> ArrayList<T> map(ArrayList<E> input) { ... }
</* type variables */> HashSet<T> map(HashSet<E> input) { ... }
</* type variables */> ImmutableList<T> map(ImmutableList<E> input) { ... }
// etc.
然后为其他情况提供一个通用方法,并让调用者指定他们想要的集合类型:
</* type variables */> Stream<T> map(Collection<E> input) { ... }
然后从具体方法中调用通用方法:
</* type variables */> ArrayList<T> map(ArrayList<E> input) {
return map((Collection<E>) input).collect(toCollection(ArrayList::new));
}
// etc.
推荐阅读
- git - 在没有 gpg 签名的情况下验证 git commit
- javascript - 如何在div内圆角图像
- apache - 从 URL 中删除字符串并重定向到它
- postgresql - 在 postgresql 中计算运行的长度
- javascript - react-native 页脚出现在 android 的键盘上方
- layer - 在单个 bblayers.conf 上集成不同的 bsp 层时出现问题
- wpf - 图像图标在自定义 Visual Studio 工具窗口 (VSIX) 中看起来格式不正确
- scala - scala 虽然用显式类型定义,但没有推断出任何东西
- vuejs2 - Vue.js 从 api 过滤对象
- android - RecyclerView 中的 Android TalkBack