1

I'm trying to convert a String list to Double list as follows:

List<String> myStringList = Arrays.asList("10.0", "10.5", "5.0");
List<?> myDoubleList = new ArrayList();
for(String s : myStringList){
        myDoubleList.add(Double.parseDouble(s));
}

When I remove the <?> from list description, it works. It breaks when I add it however. It gives me this error:

The method add(capture#6-of ?) in the type List is not applicable for the arguments (double)

Why is that ?

Tim
  • 41,901
  • 18
  • 127
  • 145
SpiderRico
  • 1,890
  • 8
  • 28
  • 48
  • 2
    See: http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p It's not a dupe, but the top answer explains the problem. – Jorn Vernee Apr 19 '17 at 10:32
  • Btw, declaring the list like this: List seems to be working. – SpiderRico Apr 19 '17 at 10:33
  • Why isn't it `List`? – Alexey Romanov Apr 19 '17 at 10:44
  • @AlexeyRomanov Because I need a generic type to avoid code duplication later. – SpiderRico Apr 19 '17 at 10:45
  • @SpiderRico It's not clear from your question how `List>` will "avoid code duplication later", but the type of `myDoubleList` can't be completely generic since it needs to support adding doubles to it. What type of lists besides `List` do you expect to use? – Wyzard Apr 19 '17 at 12:24

1 Answers1

0

The idea behind this is that List<?> represents a generic List of some unknown type. This List<?> could be List<String>, List<Double>, List<File>, or anything really, all of which count as List<?>. This means if you have a variable of type List<?>, you can't just add a Double to it, because myListOfWildcard.add(someDouble) would fail if myListOfWildcard is actually a List<String>, which it could be.

The wildcards (in particular, List<?>) aren't as useful for lists that you want to be able to contain anything. For those you generally want to use List<Object>. A wildcard would be more useful if you want to allow yourself these special cases. If you have a method and you want it to be able to accept any type of list whether it be List<String> or List<Double>, this is what List<?> is useful for, because any of these is a List<?>. However, you lose the ability to assume anything about the actual generic type parameter of the list, which means you can't just add a Double.

List<?> is a shortcut for List<? extends Object>. Wildcard lists are mostly useful as the arguments for a method; you usually don't want to create them yourself. Collection.containsAll is a good real world example of their use: In particular, Collection.containsAll accepts any Collection as its argument. It doesn't have to be a Collection<Object>, but it would if Collection<Object> where listed as its type instead of Collection<?>.

Edit: Added paragraphs from comments.

Leo Izen
  • 4,165
  • 7
  • 37
  • 56
  • *If you have a method and you want it to be able to accept any type of list whether it be List or List, this is what List> is useful for,* Why would you not use a `List` as well then? – Tim Apr 19 '17 at 13:51
  • List> is a shortcut for List extends Object>. Wildcards are mostly useful as the arguments for a method. You usually don't want to construct them yourself. See [Collection.containsAll](https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#containsAll(java.util.Collection)) as a real-world example. – Leo Izen Apr 19 '17 at 13:55
  • In particular, `Collection.containsAll` accepts any `Collection` as an argument. It doesn't *have* to be a `Collection`, which it would be if you used that. – Leo Izen Apr 19 '17 at 13:56