我代表品牌及其相关产品如下:
在代码中,这由TreeMap<String, TreeSet<String>>
表示,因为品牌将按字母顺序排序,并且不会强制执行重复的品牌或产品。由这一行创建:
private TreeMap<String, TreeSet<String>> products = loadProducts(RAW_PRODUCTS);
我还在学习Java,但在任何地方使用最通用的类型并不是优秀OO的格言之一吗?所以我有这个方法,它接受同样的Map
并进行一些处理:
void initProductList(final Map<String, Collection<String>> products)
您可以看到TreeMap
已成为Map
而TreeSet
已成为Collection
。但每当我试着打电话时:
initProductList(products);
编译器错误显示:
The method initProductList(Map<String,Collection<String>>) in the type AddAlertItem is not applicable for the arguments (TreeMap<String,TreeSet<String>>)
让它更容易阅读,这是它的不同之处:
Map<String,Collection<String>>
TreeMap<String,TreeSet<String>>
TreeSet
和Collection
之间的区别正在绊倒它。但我不确定要改变什么才能使其发挥作用。我可以向下转换方法参数以直接指定TreeSet
,但后来我觉得我限制自己,因为我可能想在其他地方使用其他类型的Collection
有没有我没想过的东西,或者是一种在不放弃更通用的方法参数的情况下完成这项工作的方法?
我在google和这里搜索了一下,但没有找到任何处理此问题的人。
答案 0 :(得分:2)
Collection
在Collections层次结构中非常高。为什么不稍微加强API参考并改为使用Set
?
void initProductList(final Map<String, ? extends Set<String>> products) {
}
通过这种方式,它明确表示您正在使用Set
,而不是List
或其他一些集合类型,因为集合的行为与列表的行为不同。
哦,它也会编译。
答案 1 :(得分:2)
我害怕@Makoto错了。
编译代码时,jvm将删除<Type>
中的泛型类型。因此,它无法识别TreeSet
和Collection
之间 extends 或 implements 的关系。只要泛型类型不同,编译器就会显示错误。但是,? extends Collection<String>
可以使用。
答案 2 :(得分:2)
您可以按如下方式将任何集合传递给您的方法:
void initProductList(final Map<String, ? extends Collection<String>> products)
答案 3 :(得分:2)
将其限制为Set
而不是Collection
,并按以下方式使用它:
void initProductList(final Map<String, ? extends Set<String>> products){}