Concat Stream of String и Integer

Я изучаю Stream, и во время одного из таких практических занятий я пытался объединить 2 потока разных типов String и Integer с помощью кода ниже:

Stream<String> fruitStream = Stream.of("Apple", "Mango", "Muskmalon", "Guvava");
Stream<Integer> vegetablesStream = Stream.of(1, 2, 3, 4);

Stream<String> mixStream = Stream.concat(fruitStream, vegetablesStream.map(i -> i.toString()));
mixStream.forEach(System.out :: println);

Он работал правильно и дал мне желаемый результат.

Затем я попытался использовать ссылку на метод:

Stream<String> mixStream = Stream.concat(fruitStream, vegetablesStream.map(Integer :: toString));

И стала выдавать ошибку:

Wrong 1st argument type. Found: 'java.util.stream.Stream<java.lang.String>', required: 'java.util.stream.Stream<? extends T>'
concat (java.util.stream.Stream<? extends T>, java.util.stream.Stream<? extends T>) in Stream cannot be applied to (java.util.stream.Stream<java.lang.String>, java.util.stream.Stream<R>)   
reason: No compile-time declaration for the method reference is found

Когда я заменил свою ссылку на метод на String :: ValueOf, она работает нормально:

Stream<String> mixStream = Stream.concat(fruitStream, vegetablesStream.map(String :: valueOf));

Я не могу понять, почему Integer::toString не прошел, а String::valueOf прошел?


person Anupam Gangrade    schedule 28.06.2017    source источник
comment
Я знал, что это должен быть дубликат...   -  person Eugene    schedule 28.06.2017


Ответы (1)


Сообщение об ошибке должно быть Ambiguous method reference: both toString() and toString(int) from the type Integer are eligible. Это происходит потому, что здесь можно использовать как toString, так и toString(int).

Это могло быть и то, и другое:

  .map(i -> i.toString(i))
  .map(i -> i.toString())      

И это прекрасно работает, потому что String::valueOf не имеет такого перегруженного метода, и поэтому компилятор с этим согласен.

person Eugene    schedule 28.06.2017
comment
Спасибо, Евгений, за разъяснения. Извиняюсь за дублирующийся вопрос, но я не смог найти точно такой же сценарий. Возможно, мне придется улучшить свои навыки поиска :) - person Anupam Gangrade; 28.06.2017
comment
Object::toString также будет работать. Я столкнулся с этой проблемой, когда IntelliJ пометил лямбду i -> i.toString() с помощью Can be replace с ссылкой на метод. Я предполагаю, что это сообщение генерируется в результате простой проверки синтаксиса без учета возможной двусмысленности? - person Greg H; 26.12.2017
comment
@GregH, учитывая, как много вещей может поместиться в этот заменитель ссылок на методы, я думаю, что только проверка синтаксиса является разумной вещью для отчета; ведь IntelliJ не умеет читать мысли - person Eugene; 26.12.2017