Получить доступ

Зачем в JDK помимо Function<T,R> существуют IntFunction, ToIntFunction и IntPredicate?

MiddleЛямбды и Stream API
Коротко

Дженерики работают только со ссылочными типами, поэтому Function<Integer, Integer> упаковывает и распаковывает значения на каждом вызове. Специализации (IntFunction, ToIntFunction, IntPredicate, IntUnaryOperator) работают с примитивами напрямую — без аллокаций.

  • По той же причине есть IntStream, LongStream, DoubleStream
  • mapToInt и sum вместо map и reduce(Integer::sum)
  • Набор неполный: нет специализаций для byte, short, char, float

А ещё Valhalla обещает дженерики над примитивами

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Дженерики не работают с примитивными типами, поэтому Function<Integer, Integer> на каждом вызове упаковывает аргумент и распаковывает результат — на большом потоке данных это заметная нагрузка на аллокацию и сборщик. Специализированные интерфейсы принимают и возвращают примитивы напрямую. По той же причине существуют IntStream, LongStream и DoubleStream, а у обычного стрима есть методы mapToInt и mapToObj для перехода между мирами — попутно примитивные стримы дают полезные sum, average и summaryStatistics. Практический ориентир: в обычном коде разница несущественна, но в вычислительно нагруженных участках со стримами по числам примитивные варианты стоит использовать сознательно.

Что хотят услышать

  • Цена упаковки.
  • Связь с примитивными стримами.

Частые ошибки

  • Строить тяжёлые числовые конвейеры на Stream<Integer>.
  • Считать, что JIT всегда устранит упаковку.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Чтобы избежать упаковки примитивов: обобщённые интерфейсы работают только со ссылочными типами, и каждый вызов создавал бы объект-обёртку
  • ✗Чтобы поддержать сигнатуры с несколькими аргументами
  • ✗Для обратной совместимости с кодом до Java 5
  • ✗Чтобы разрешить бросать проверяемые исключения из лямбд

Что спросят дальше

  • Чем boxed() отличается от mapToObj?
  • Как лямбда может бросить проверяемое исключение?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем