У меня некоторая путаница, и я хочу прояснить свою концепцию.
Допустим, мы следующее утверждение:
.map(i -> Tests.doubleIt(i))
Итак, при использовании :: как:
.map(Tests::doubleIt)
Итак, параметр i внутренне принимается doubleIt и внутренне передается методу doubleIt?
Можем ли мы узнать внутреннее устройство, как i принимается и передается методу doubleIt в случае ::?




Код в map вызывает функцию, которую вы ему передаете (doubleIt), передавая ей аргумент напрямую, который doubleIt получает в качестве своего первого формального параметра. Напротив, с вашей лямбда-версией map вызывает вашу лямбда с аргументом, который ваша лямбда получает в качестве параметра i, а затем ваша лямбда вызывает doubleIt, используя i в качестве аргумента. Так что это более прямая ссылка на метод (теоретически), чем с лямбдой.
Что, если у нас есть несколько параметров?
@ user10796624 - Точно такая же ситуация. Метод, который вы передаете, должен соответствовать тому, что ожидает map (в случае map, метод с одним формальным параметром типа int [если я не ошибаюсь]). Но если вы вызываете метод, который ожидает обратного вызова, который принимает несколько параметров, то, конечно, когда он вызывает этот метод, он передаст ему несколько аргументов, по одному для каждого параметра.
и все множественные параметры будут размещены на своих местах, например p1, p1, p3 будет doubleIt(p1,p2,p3), я прав?
@ user10796624 - Конечно. Это просто вызов метода. В этом нет ничего особенного.
So, do the i parameter is internally received by the doubleIt and internally passed to doubleIt method?
.map(i -> Tests.doubleIt(i))
строка выше читается как «если элемент представлен как i, вызовите метод doubleIt с текущим элементом в качестве ввода».
Другими словами, вы указываете, «что» должно быть сделано, а «как» это должно быть сделано - это внутренняя деталь реализации.
Can we know the internals how the i is received and passed to the doubleIt method in case of ::?
Когда вы передаете Tests::doubleIt, вы, по сути, передаете «ссылку» на метод doubleIt, и для каждого элемента источника метод map вызывает функцию doubleIt, передавая текущий элемент в качестве ввода.
Больше ничего нет.
Чтения, которые могут оказаться полезными:
И все это делается internally, не нужно делать для этого лишней работы, правда?
@ user10796624 Да, основная идея функционального программирования в JDK8 заключается в том, что пользователь указывает только «что», а «как» - это внутренняя деталь реализации.
@ user10796624 пожалуйста. добавил несколько блогов, которые могут оказаться вам полезными. всего наилучшего :)
Это становится проще, если рассматривать отдельно тип функционального интерфейса и само значение потока.
С одной стороны, предположим упрощенный настраиваемый класс, который содержит целое число и имеет метод map:
class MyObject {
int value = 0;
MyObject map(Function<Integer, Integer> f) {
this.value = f.apply(this.value);
return this;
}
}
Этот класс MyObject знает элемент, который он содержит, поэтому, когда его метод map выполняется, класс знает, где найти значение, которое функция примет в качестве параметра. Грубо говоря, именно так потоки используют эту функцию.
С другой стороны, создается экземпляр Function<Integer, Integer>, который будет передан в map.
Как вы указали, вы можете использовать Tests::doubleIt или i -> Tests.doubleIt(i) для передачи аргумента map (в этом случае не имеет значения, какой метод, результирующий объект Function будет вызываться таким же образом).
Я пытаюсь понять: это две разные проблемы: MyObject будет знать, как получить элементы, переданные в Function.apply, в то время как класс, вызывающий map, будет отвечать за обеспечение логики. Эта «логика» и есть экземпляр Function.
Когда вы смотрите на них по отдельности, ответ на ваш вопрос становится очевидным. Я считаю, что это поможет реализовать аналогичный код.
Я не совсем понимаю, что вы имеете в виду под «полученным внутри страны». Но
mapожидает ввода точно аргумента один и возврата определенного типа. ЗаписываяTests::doubleIt, компилятор ищет метод с именемdoubleItвTests, который принимает аргумент один и возвращает определенный тип.