The wildcard syntax was deliberately designed to (mis)lead people to believe it matches any type. This works for simple cases.
Up vote 4 down vote favorite 1 share g+ share fb share tw.
I have a HashMap where the values are ArrayLists, and I'm trying to write a function to accept generic instances of these HashMaps HashMap> myMap = new HashMap>(); public static void foo(HashMap> a) {} public static void bar(HashMap> a) {} // Compilation Failure! Foo(myMap); // This works, but why do I need? Extends ArrayList bar(myMap) The error message is The method foo(HashMap>) in the type Example is not applicable for the arguments (HashMap>).
Why do I need to have a wildcard for the extends ArrayList? I thought that by having ArrayList(without the? Extends), I could restrict the function to only HashMaps with ArrayList values.
I also know that the following generic method works: public static void printer(HashMap> list) { } Which behaves how I thought ArrayList would work. Can someone explain the subtleties here? Java generics arraylist hashmap wildcard link|improve this question edited Jul 6 '11 at 22:30Pa?
Lo Ebermann22.4k41740 asked Jul 6 '11 at 21:20Kevin211.
Either tell us the exact compiler error which is generated by foo, or give us an example of the code inside foo which causes the error. In fact, both pieces of information would help greatly – Ken Wayne VanderLinde Jul 6 '11 at 21:25 Works On My Machine – Ed Staub Jul 6 '11 at 21:28 The method foo(HashMap>) in the type Example is not applicable for the arguments (HashMap>) – Michael Brewer-Davis Jul 6 '11 at 21:30 The error I get is the same as Michael Brewer – Kevin Jul 6 '11 at 21:46.
The wildcard syntax was deliberately designed to (mis)lead people to believe it matches any type. This works for simple cases List // OK, right is subtype of left But remember, it only works on the 1st level, not deeper List > // FAIL This is fine List> > because of the new 1st level?. If S is subtype of T, G is subtype of G.
Apply that in case ofS=List, T=List.
I did verify this is the case but I'm just curious where it's documented. – Bala R Jul 6 '11 at 21:34 @Bala angelikalanger.com/GenericsFAQ/JavaGener... – Sean Patrick Floyd Jul 6 '11 at 21:36 ok. Also found a similar answer with lots of references stackoverflow.com/questions/3575681/… – Bala R Jul 6 '11 at 21:37 Bala R: First hit on Google hold a good tutorial: download.oracle.com/javase/tutorial/extra/generics/… – Mathias Schwarz Jul 6 '11 at 21:37 in JLS3, #4.10.2 subtyping rules.
You'll see only the 1st level wildcard is addressed. Also in #5.1.10 "Capture conversion is not applied recursively. " – irreputable Jul 6 '11 at 21:42.
The type HashMap> means about a map which maps keys of some unknown (fixed) type to lists, each of which has elements of some unknown fixed type. A concrete instantiation of such a map would be, for example: new HashMap>(); This is a map in which we can add arbitrary ArrayLists as values, and for values (lists) we get out of them we don't know anything about the parameter type. The type HashMap> means a map from strings to lists of integer.
This is a map in which we can only add ArrayLists of Integers as values, not arbitrary ArraysLists. Thus, it cannot be a subtype of the type 2 (since it allows less than it). (Type 1 is a supertype of 2, which also lets the key type unknown.
) The type HashMap> means a map from strings to some unknown type, which is only known to be a subtype of ArrayList. In such a map we can't insert anything (as value), but all values we get out of it are guaranteed to be of type ArrayList, i.e. A arraylist of something unknown (which may be another something for each list).
We can insert new String keys, but only with a null value. Both type 2 and type 3 are subtypes of type 4 (since both ArrayList and ArrayList fulfill the extends ArrayList condition), but not of each other. HashMap> is like 4, but we don't know the key type, either.
This means we can't really do anything with the map, apart from iterating it (or looking up values for keys - get() takes an Object argument, not K) and removing stuff. For the values we retrieve, we only can iterate and remove stuff, not insert or even reorder anything. (I.e.
Type 4 is a subtype of type 5. ) The method argument type HashMap> with type variables means a map from some type K to lists of some type V, where K and V are decided by the caller of the method. The type 3 obviously fits this (with ), thus you are allowed to call this method.
You can't really put new keys into the map, since your method does not know what K is, but you could map existing keys to new values. You can use new ArrayList() (and put these elements into the map as values), but you can only put existing V objects from your existing lists into these lists. Still a lot more possible than with type 5.
Just a side note: You should have used the more general types Map and List instead of HashMap and ArrayList for your methods, since most certainly the method will work on any type of map/list and does not care about the specific implementation. You also would use Map> myMap = new HashMap>(); to declare and initialize your variable. (You can still put ArrayList objects as values.
).
It's very simple. HashMap is not a subtype of HashMap even if V is a subtype of W. (You know this already, right?
) Here, V is ArrayList, and W is ArrayList. (What matters is that they are different. ) Yes, ArrayList is a subtype of ArrayList, but that's what we covered earlier, i.e.
It's irrelevant. However, HashMap is a subtype of HashMap, because of the wildcard.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.