Java › Functional Interfaces & Method References
What is the difference between UnaryOperator<T> and Function<T,T>, and why does UnaryOperator exist as a separate, more specific interface?
IntermediateAnswer
UnaryOperator<T> extends Function<T,T> (a function whose input and output are the same type), existing as a more specific, semantically clearer name specifically for the common case where a transformation preserves its input's type (like a String-to-String transformation, or doubling a number) -- functionally it's interchangeable with Function<T,T> (inheriting the same apply() method plus andThen/compose), but using UnaryOperator communicates the same-type constraint more clearly to readers and provides a convenient static identity() factory method that Function alone doesn't offer with quite the same clarity.
UnaryOperator<String> toUpper = String::toUpperCase;
UnaryOperator<Integer> square = x -> x * x;
// Equivalent to Function<String, String> and Function<Integer, Integer>, but more semantically clear
UnaryOperator<String> identity = UnaryOperator.identity(); // returns its input unchanged
System.out.println(identity.apply("test")); // "test"Real-world example A List.replaceAll() call (which specifically requires a UnaryOperator<T> parameter, not just any Function<T,T>) is used to transform every element of a list in place, the API deliberately choosing the more semantically specific UnaryOperator type to communicate that the transformation must preserve the list's element type.