Использование Unaryoperator и Binaryoperator, когда у меня есть функция в Java 8 - PullRequest
0 голосов
/ 30 января 2019

В Java 8 предусмотрено множество функциональных интерфейсов, таких как UnaryOperator, BinaryOperator, Function и т. Д.

Код

UnaryOperator<Integer> uop1 = (Integer i) -> i * 10;
BinaryOperator<Integer> uop2 = (Integer i1, Integer i2) -> i1 * i2 * 10;

всегда можно записать с использованием функции, как показано ниже,

Function<Integer, Integer> f1 = (Integer i) -> i * 10;
BiFunction<Integer, Integer, Integer> f2 = (Integer i1, Integer i2) -> i1 * i2 * 10;

Итак, что такое использование этих операторских интерфейсов?Они достигают чего-то отличного от того, что может быть достигнуто с помощью функции?

Ответы [ 4 ]

0 голосов
/ 30 января 2019

Функциональные интерфейсы должны быть максимально специализированными.

Наличие

Function<Integer, Integer> f1 = (Integer i) -> i * 10;

Вместо:

UnaryOperator<Integer> uop1 = (Integer i) -> i * 10;

на самом деле является запахом кода (для этого также есть правило сонара squid:S4276).

Простая причина этого заключается в том, что эти интерфейсы были созданы, чтобы избежать передачи ненужных параметров типа n раз, пока у вас есть только один.

public interface UnaryOperator<T> extends Function<T, T>

Таким образом, написание Function<T, T> просто дольше и не нужно.

Говоря о других интерфейсах, таких как: IntConsumer против Consumer<Integer> или DoubleToIntFunction против Function<Double, Integer>, где второй вариант может привести к ненужному автобоксированию и может снизить производительность.

Вот почему использование более специфичного и подходящего интерфейса делает ваш код более чистым и защищает вас от неожиданностей.

0 голосов
/ 30 января 2019

UnaryOperator и BinaryOperator являются ярлыками для Function и BiFunction, когда тип возвращаемого типа совпадает с типом ввода.Я думаю, что они также могут иметь разные значения, у операции и функции могут быть разные интерпретации в зависимости от вашего контекста, это, по сути, для читабельности кода, а не по техническим причинам.

0 голосов
/ 30 января 2019

Да, они функционально идентичны.Они даже расширяют классы, о которых вы говорите, и используют те же SAM .Интерфейсы UnaryOperator и BinaryOperator определяют только статические методы.

public interface UnaryOperator<T> extends Function<T, T>

public interface BinaryOperator<T> extends BiFunction<T,T,T>

Они просто для краткости.Зачем указывать параметр типа 2 или 3 раза, когда вы можете сделать это один раз?

0 голосов
/ 30 января 2019

Они здесь для вашего удобства.Вы можете сэкономить на написании BiFunction<Integer, Integer, Integer> и просто написать / использовать BinaryOperator<Integer> вместо этого.Дополнительное преимущество: вы можете убедиться, что данная функция принимает один или два параметра одного и того же типа и возвращает точно такой же тип без гораздо большей записи.

Дополнительно из-за характера BinaryOperator<T> itимеет больше смысла помещать что-то вроде minBy и maxBy, что на самом деле не имеет большого смысла помещать в BiFunction<T, U, R>.Поскольку заданные параметры имеют одинаковый тип и тип возвращаемого значения также является одинаковым, компаратор может быть легко применен ... очень удобно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...