13

What am I missing? Why do I have to use Object::toString below and not Integer::toString? Does it have anything to do with type erasure with generics?

Arrays.asList(1,2,3).stream().map(Integer::toString).forEach(System.out::println); //Won't compile

Arrays.asList(1,2,3).stream().map(Object::toString).forEach(System.out::println); //Compiles and runs fine
Brian Goetz
  • 90,105
  • 23
  • 150
  • 161
sat
  • 5,489
  • 10
  • 63
  • 81
  • 2
    BTW You can just write `Arrays.asList(1,2,3).forEach(System.out::println);` or `Stream.of(1,2,3).forEach(System.out::println);` or `IntStream.rangeClosed(1, 3).forEach(System.out::println);` – Peter Lawrey Jan 11 '15 at 09:30
  • possible duplicate of [How to fix ambigous type on Java8 method reference (toString of an Integer)](http://stackoverflow.com/questions/21873829/how-to-fix-ambigous-type-on-java8-method-reference-tostring-of-an-integer) – Holger Jan 11 '15 at 16:51

1 Answers1

25

This has nothing to do with type erasure.

Look at the error message :

(argument mismatch; invalid method reference
  reference to toString is ambiguous
    both method toString(int) in Integer and method toString() in Integer match)

The Integer class has two toString methods that match the functional interface expected by the map() method. One is static with an int argument, and the other is the toString() method that overrides Object's toString().

The compiler doesn't know if you want to execute this :

Arrays.asList(1,2,3).stream().map(i->Integer.toString(i)).forEach(System.out::println);

or this :

Arrays.asList(1,2,3).stream().map(i->i.toString()).forEach(System.out::println);
Eran
  • 387,369
  • 54
  • 702
  • 768
  • 1
    plus one, well covered. – Peter Lawrey Jan 11 '15 at 09:28
  • 2
    You can use `IntStream.of(1, 2, 3).mapToObj(Integer::toString) .forEach(System.out::println);` which is not ambiguous as explained [here](http://stackoverflow.com/a/21876077/2711488). – Holger Jan 11 '15 at 16:54
  • I get a different error message though (and perhaps why I couldn't understand what was going on). The error message that I get (in the IDE) reads - "map (java.util.function.Function super java.lang.Integer, ? extends R>) in Stream cannot be applied to ()". What can anyone make of that? – sat Jan 11 '15 at 19:09
  • @sat I don't know why you got that error message. I tried your code [here](http://www.compilejava.net/) and got the error mentioned in my answer. – Eran Jan 11 '15 at 19:17
  • @sat: if you have a question specific to an IDE you should include the name of the IDE you have used. – Holger Jan 12 '15 at 10:22