46

When doing this

Stream.of(1, 32, 12, 15, 23).map(Integer::toString);

I get an ambiguous type error. Understandably, the compiler can't tell if I mean toString(int) or toString() from Integer.

When not using a method reference, I might have gotten out of this with an explicit cast or write out the generics long hand, but how can I let the compiler know what I mean here? What syntax (if any) can I use to make in unambiguous?

Lii
  • 11,553
  • 8
  • 64
  • 88
Toby
  • 9,523
  • 8
  • 36
  • 59

3 Answers3

54

There is no way to make method references unambiguous; simply said, method references are a feature that is just supported for unambiguous method references only. So you have two solutions:

  1. use a lambda expression:

    Stream.of(1, 32, 12, 15, 23).map(i->Integer.toString(i));
    
  2. (preferred, at least by me) Use a stream of primitive int values when the source consists of primitive int values only:

    IntStream.of(1, 32, 12, 15, 23).mapToObj(Integer::toString);
    

    This will use the static Integer.toString(int) method for consuming the int values.

Holger
  • 285,553
  • 42
  • 434
  • 765
34

Since Integer.toString() overrides Object.toString(), in this particular case you could fix it as follows:

Stream.of(1, 32, 12, 15, 23).map(Object::toString);
SlavaSt
  • 1,493
  • 1
  • 16
  • 19
23

Your main options, using method references, are:

Stream.of(1, 32, 12, 15, 23).map(String::valueOf);
IntStream.of(1, 32, 12, 15, 23).mapToObj(Integer::toString);

Your current version could mean i -> i.toString() or i -> Integer.toString(i).

assylias
  • 321,522
  • 82
  • 660
  • 783