#java #java_8 #lambda #java_faq
Вопрос по использованию Function.identity() метода.
Допустим, есть следующий код:
Arrays.asList("a", "b", "c")
.stream()
.map(Function.identity()) // <- Этот кусок
.map(str -> str) // <- равен этому.
.collect(Collectors.toMap(
Function.identity(), // <-- А этот
str -> str)); // <-- равен этому.
Должен ли я использовать Function.identity() вместо str->str(или наоборот)? Я думаю,
что второй вариант более читабелен и понимаем(допустим, если новый человек не знает
что делает identity). Но есть ли «реальная» причина, из-за которой следует отдать предпочтение
одному из способов?
Ответы
Ответ 1
Первоначально кажется, что у этих двух способов нет отличия, ведь реализация identity() такова: staticFunction identity() { return t -> t; } Однако Function.identity() всегда будет возвращать один и тот же экземпляр(обоснование этого решения), в то время как t -> t не только будет создавать новый экземпляр, но даже будет иметь отдельный класс реализации. Для более подробной информации смотрите здесь. Причина в том, что компилятор генерирует синтетический метод, содержащий тело лямбда выражений(случае t -> t это будет return t;) и указывает среде выполнения создать реализацию функционального интерфейса, вызывающего этот метод. Поэтому использование Function.identity() вместо t -> tможет сэкономить немного памяти, но совсем небольшое количество, поэтому это не должно влиять на ваше решение, если вы считаете, что t -> t более читабельно, чем Function.identity(). Также в некоторых методах нельзя вызвать Function.identity(). Допустим, есть такой список: List list ... ... Код ниже отлично скомпилируется: int[] arrayOK = list.stream().mapToInt(i -> i).toArray(); Но если попытаться скомпилировать следующий код, то будет ошибка компиляции: int[] arrayProblem = list.stream().mapToInt(Function.identity()).toArray(); Она произойдет из-за того что mapToInt ожидает ToIntFunction, которая не связана с Function. Также у ToIntFunction нет метода identity().
Комментариев нет:
Отправить комментарий