Функциональные интерфейсы должны быть максимально специализированными.
Наличие
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>
, где второй вариант может привести к ненужному автобоксированию и может снизить производительность.
Вот почему использование более специфичного и подходящего интерфейса делает ваш код более чистым и защищает вас от неожиданностей.