Важно различать, что делает вызов Stream#mapToInt(ToIntFunction)
и что делает аргумент ToIntFunction
.
- Вызов
mapToInt
- это , что будет делать поток (т.е. отобразить элементы на int
).
- Аргумент
ToIntFunction
равен как поток собирается сопоставить каждый элемент с int
.
Могли бы они включить метод без аргументов mapToInt
, который неявно анализирует String
с int
с? Да, но посмотрите, насколько хорошо это работает для Stream#sorted()
- и эта ситуация далеко не так произвольна или неоднозначна, как метод без аргументов mapToInt
.
Метод no-arg sorted
предполагает, что элементы Comparable
являются фундаментальным, стандартизированным и широко распространенным интерфейсом в Java - любой класс может реализовать интерфейс (тогда как есть только один класс, который может быть * 1035). *). Таким образом, хотя метод не является типобезопасным, можно утверждать, что прецедент достаточно распространен, чтобы оправдать его существование.
Тем не менее, метод no-arg mapToInt
, который предполагает, что элементы равны String
s и анализирует их содержимое в int
, является весьма специфическим вариантом использования. Почему такой общий API предлагает такую специфическую операцию? Это было бы совершенно произвольное решение без разумного обоснования. Например, почему бы не сопоставить каждый String
с length
? И почему String
обрабатывается специально, а не какой-то другой тип (типы)? Следовательно, метод принимает аргумент ToIntFunction
, который описывает как для сопоставления элементов с int
на индивидуальной основе.
Может быть полезно отметить, что Integer::parseInt
- это ссылка на метод , что является сокращением для тривиального лямбда-выражения . Оба являются реализацией функционального интерфейса , который является менее подробным вариантом, чем использование анонимного класса . Другими словами, вы создаете новый экземпляр ToIntFunction
и передаете его в качестве аргумента.
Все перечисленные ниже функционально эквивалентны:
// method reference
stream.mapToInt(Integer::parseInt)
// lambda expression
stream.mapToInt((String value) -> Integer.parseInt(value)) // explicit parameter types
stream.mapToInt(value -> Integer.parseInt(value)) // implicit parameter types
// anonymous class
stream.mapToInt(new ToIntFunction<>() {
@Override
public int applyAsInt(String value) {
return Integer.parseInt(value);
}
})
Где stream
является Stream<String>
.