Лямбды в Java 8, что лучше использовать - Function.identity() или t->t?

135
17 января 2020, 05:50

Вопрос по использованию 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). Но есть ли «реальная» причина, из-за которой следует отдать предпочтение одному из способов?

Answer 1

Первоначально кажется, что у этих двух способов нет отличия, ведь реализация identity() такова:

static <T> Function<T, T> identity() {
    return t -> t;
}

Однако Function.identity() всегда будет возвращать один и тот же экземпляр(обоснование этого решения), в то время как t -> t не только будет создавать новый экземпляр, но даже будет иметь отдельный класс реализации. Для более подробной информации смотрите здесь.

Причина в том, что компилятор генерирует синтетический метод, содержащий тело лямбда выражений(случае t -> t это будет return t;) и указывает среде выполнения создать реализацию функционального интерфейса, вызывающего этот метод.

Поэтому использование Function.identity() вместо t -> tможет сэкономить немного памяти, но совсем небольшое количество, поэтому это не должно влиять на ваше решение, если вы считаете, что t -> t более читабельно, чем Function.identity().

Также в некоторых методах нельзя вызвать Function.identity(). Допустим, есть такой список:

List<Integer> list ... 
...

Код ниже отлично скомпилируется:

int[] arrayOK = list.stream().mapToInt(i -> i).toArray();

Но если попытаться скомпилировать следующий код, то будет ошибка компиляции:

int[] arrayProblem = list.stream().mapToInt(Function.identity()).toArray();

Она произойдет из-за того что mapToInt ожидает ToIntFunction, которая не связана с Function. Также у ToIntFunction нет метода identity().

READ ALSO
Самопроизвольный выход из цикла в AsyncTask

Самопроизвольный выход из цикла в AsyncTask

Есть цикл получения данных из xml файлаОн выполняется в AsyncTask doInBackground

130
Ошибка при возврате List в responce SOAP

Ошибка при возврате List в responce SOAP

Ошибка при возврате List в responce SOAP

146
Impact, Charcoal на ipad не работают

Impact, Charcoal на ipad не работают

Подскажите, почему эти шрифты Impact, Charcoal не работают на ipad? Можно ли как-то проверить, поддерживает ipad эти шрифты?

179
Фоновая картинка на всё разрешение окна?

Фоновая картинка на всё разрешение окна?

Как это делается или как называется ? Пример-http://vse-gotovocom/

152