Search code examples
javafunctional-programmingfunctional-interface

A summary of the parameters and return type of functional interfaces in the package java.util.function


I'm looking for a table of parameters and return type of the single abstract method (SAM) of all interfaces in java.util.function.


Solution

  • Here's a table of all 43 interfaces in the package, plus some other notable interfaces. This arrangement should make it easy to see the naming patterns in the package. The table is designed to work as a comment in a .java class file. Open the file in eclipse (or any other IDE that can resolve class names in comments). You should be able to hover over the names and see their javadocs. A ctrl-click will open the interfaces source code if you've properly attached the java source code.

    (Surprisingly, this doesn't seem to work in InteliJ. Let me know if there's a setting I'm missing.)

    import java.util.function.Function;  //Prevent "which package?" popups
    import java.util.function.Predicate; 
    

    Interfaces whose abstract method declares "throws Exception" denoted with *

    /*  Param\Return   void                  boolean                R                  
                       ----                  -------                -                  
    void               Runnable              BooleanSupplier        Supplier<R>        
    void               AutoCloseable*                               Callable<R>*        
    
    T                  Consumer<T>           Predicate<T>           Function<T,R>      
    R                                                               UnaryOperator<R>   
    
    T, U               BiConsumer<T,U>       BiPredicate<T,U>       BiFunction<T,U,R>  
    R, R                                                            BinaryOperator<R>  
    
    int                IntConsumer           IntPredicate           IntFunction<R>     
    T, int             ObjIntConsumer<T>                            
    
    long               LongConsumer          LongPredicate          LongFunction<R>    
    T, long            ObjLongConsumer<T>                           
    
    double             DoubleConsumer        DoublePredicate        DoubleFunction<R>  
    T, double          ObjDoubleConsumer<T>
    
        Param\Return   int                   long                   double
                       ---                   ----                   ------
    void               IntSupplier           LongSupplier           DoubleSupplier
    
    T                  ToIntFunction<T>      ToLongFunction<T>      ToDoubleFunction<T>
    
    T,U                ToIntBiFunction<T,U>  ToLongBiFunction<T,U>  ToDoubleBiFunction<T,U>
    
    int                IntUnaryOperator      IntToLongFunction      IntToDoubleFunction
    int, int           IntBinaryOperator                                  
    
    long               LongToIntFunction     LongUnaryOperator      LongToDoubleFunction
    long, long                               LongBinaryOperator      
    
    double             DoubleToIntFunction   DoubleToLongFunction   DoubleUnaryOperator
    double, double                                                  DoubleBinaryOperator */
    

    Some examples of use:

    // Lambda using Runnable
    new Thread(() -> System.out.println(Thread.currentThread().getName())).start();
    
    Optional<String> opt = Optional.of("Meh");
    
    // Lambda using Predicate<? super String>;
    opt = opt.filter( s->s.equalsIgnoreCase("meh") ); 
    System.out.println(opt+" <-- opt"); 
    
    // Lambda using Consumer<? super String>;
    opt.ifPresent( s->System.out.println(s) );
    
    // Lambda using Function<? super String, ? extends String>;
    opt = opt.map(s->s+"!").map(s->s+"!");
    System.out.println(opt+" <-- opt");
    
    // Lambda using Supplier<? extends IllegalArgumentException>;
    opt.orElseThrow( ()->new IllegalArgumentException("Should not be empty.") );
    opt = Optional.empty();
    opt.orElseThrow(
        ()->new IllegalArgumentException("Empty?  Who said you could be empty?")
    );
    
    Thread-0
    Optional[Meh] <-- opt
    Meh
    Optional[Meh!!] <-- opt
    Exception in thread "main" java.lang.IllegalArgumentException: 
      Empty?  Who said you could be empty?
        at functionalinterfacestudy.AllLambdas.lambda$6(AllLambdas.java:110)
        at functionalinterfacestudy.AllLambdas$$Lambda$7/1392838282.get(Unknown Source)
        at java.util.Optional.orElseThrow(Unknown Source)
        at functionalinterfacestudy.AllLambdas.main(AllLambdas.java:110)
    

    Also, this book presents the package with some detailed tables.

    And, while it's not much of a table, it's always good to read the official package summery.

    The JDK actually has 57 Interfaces sporting the @FunctionalInterface annotation. Those not mentioned above include:

    import java.io.FileFilter;       // Aren't name collisions fun?
    import java.io.FilenameFilter;
    import java.util.Comparator;
    import java.util.logging.Filter;
    
    /*
    
    Interface                        Single Abstract Method     
    ---------                        ----------------------
    KeyEventDispatcher:              boolean dispatchKeyEvent(KeyEvent e);
    KeyEventPostProcessor:           boolean postProcessKeyEvent(KeyEvent e);
    FileFilter:                      boolean accept(File pathname);
    FilenameFilter:                  boolean accept(File dir, String name);
    Thread.UncaughtExceptionHandler: void uncaughtException(Thread t, Throwable e);
    DirectoryStream<T>.Filter<T>:    boolean accept(T entry) throws IOException;
    PathMatcher:                     boolean matches(Path path);
    TemporalAdjuster:                Temporal adjustInto(Temporal temporal);
    TemporalQuery<R>:                R queryFrom(TemporalAccessor temporal);
    Comparator<T>:                   int compare(T o1, T o2);
    Filter:                          public boolean isLoggable(LogRecord record);
    PreferenceChangeListener:        void preferenceChange(PreferenceChangeEvent evt);    
    
    */
    

    However, the JDK has many interfaces that meet all the requirements to be a functional interface that don't have the @FunctionalInterface annotation (such as AutoClosable). The missing annotation doesn't keep them from working as a functional interface. It's used to force the compiler to throw an error when an interface violates the definition of a functional interface. In a way, it's a promise not to expand the set of abstract methods you must override when you implement the interface (it's ok to add default methods since they always have their own implementation). Which leaves me wondering: why it isn't @FunctionalInterface used on all the interfaces in the JDK that qualify?