Reputation: 293
I'm representing brands with their associated products like so:
In code this is represented by a TreeMap<String, TreeSet<String>>
, as the brands will stay sorted alphabetically and enforce no duplicate brands or products. Created by this line:
private TreeMap<String, TreeSet<String>> products = loadProducts(RAW_PRODUCTS);
I'm still learning Java, but isn't one of the maxims of good OO to use the most-general type wherever you can? So I have this method that takes in this same Map
and does some processing:
void initProductList(final Map<String, Collection<String>> products)
And you can see the TreeMap
has become Map
and the TreeSet
has become Collection
. But whenever I try to call:
initProductList(products);
The compiler error shows:
The method initProductList(Map<String,Collection<String>>) in the type AddAlertItem is not applicable for the arguments (TreeMap<String,TreeSet<String>>)
to make it easier to read, this is the difference it's confused on:
Map<String,Collection<String>>
TreeMap<String,TreeSet<String>>
The difference between TreeSet
and Collection
is tripping it up. But I'm not sure what to change to make it work. I could downcast the method parameters to specify the TreeSet
directly, but then I feel I'd be limiting myself as I may want to use another type of Collection
elsewhere.
Is there something I'm not thinking of, or a way to make this work without giving up the more-generic method parameters?
I've searched a bit on google and here and not found anyone dealing with this issue.
Upvotes: 1
Views: 82
Reputation: 106460
Collection
is pretty high up the Collections hierarchy. Why not strengthen the API reference a little bit and go with Set
instead?
void initProductList(final Map<String, ? extends Set<String>> products) {
}
This way, it's explicitly clear that you're working with Set
, and not List
or some other collection type, as sets behave differently than lists do.
Oh, and it'll also compile.
Upvotes: 2
Reputation: 19700
Limit it to a Set
and not a Collection
and use it as below:
void initProductList(final Map<String, ? extends Set<String>> products){}
Upvotes: 2
Reputation: 7986
You can pass any collection to your method as follows :
void initProductList(final Map<String, ? extends Collection<String>> products)
Upvotes: 2
Reputation: 588
I'm afraid @Makoto has got it wrong.
When compiling the codes, jvm will erase the generic type in <Type>
. So it can't recognize the relationship of extends or implements between TreeSet
and Collection
. As long as the generic types are different, the compiler will show an error. However, ? extends Collection<String>
will work.
Upvotes: 2