Java 8 added functional programming constructs, including the Function
class and its associated identity()
method.
Here's the current structure of this method:
// Current implementation of this function in the [JDK source][1]
static <T> Function<T, T> identity() {
return t -> t;
}
// Can be used like this
List<T> sameList = list.stream().map(Function.identity()).collect(Collectors.toList());
However, there's a second way to structure it:
// Alternative implementation of the method
static <T> T identity(T in) {
return in;
}
// Can be used like this
List<T> sameList = list.stream().map(Function::identity).collect(Collectors.toList());
There's even a third way to structure it:
// Third implementation
static final Function<T, T> IDENTITY_FUNCTION = t -> t;
// Can be used like this
List<T> sameList = list.stream().map(Function.IDENTITY_FUNCTION).collect(Collectors.toList());
Of the three approaches, the first one that is actually used in the JDK looks less memory efficient, as it appears to be creating a new object (lambda) on every use, while the second and third implementations don't. According to this SO answer that's not actually the case, so ultimately all three approaches seem relatively equivalent performance-wise.
Using the second approach allows the method to be used as a method reference, which is similar to how many other standard library methods are used in functional constructs. E.g. stream.map(Math::abs)
or stream.map(String::toLowerCase)
.
Overall, why use the first approach, which looks (though ultimately isn't) less performant and is different from other examples?