The purpose of these interfaces is to allow working with primitive types directly. This saves automatic boxing and automatic unpacking, which makes these interfaces (and the related IntStream , LongStream and DoubleStream that depend on them) more efficient.
For example, instead of using Function<Integer,R> , which has a method that accepts Integer and creates a result of type R , you use IntFunction<R> , which has a method that accepts int and produces a result of type R If you pass an int this function, you will avoid the box that would happen if you pass the same int method to the Function<Integer,R> method.
source share