【问题标题】:A summary of the parameters and return type of functional interfaces in the package java.util.functionjava.util.function包中函数接口的参数和返回类型总结
【发布时间】:2015-01-02 13:56:03
【问题描述】:

我正在寻找java.util.function 中所有接口的单一抽象方法 (SAM) 的参数和返回类型表。

【问题讨论】:

    标签: java functional-programming functional-interface


    【解决方案1】:

    这是包中所有 43 个接口的表格,以及其他一些值得注意的接口。这种安排应该可以很容易地看到包中的命名模式。该表旨在用作 .java 类文件中的注释。在 eclipse(或任何其他可以解析 cmets 中的类名的 IDE)中打开该文件。您应该能够将鼠标悬停在名称上并查看它们的 javadocs。 ctrl-click 将打开接口源代码,如果你正确地attached the java source code

    (令人惊讶的是,这在 InteliJ 中似乎不起作用。如果我缺少某个设置,请告诉我。)

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

    抽象方法声明“抛出异常”的接口,用 * 表示

    /*  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 */
    

    一些使用示例:

    // 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)
    

    另外,本书还提供了一些detailed tables的包。

    而且,虽然它不是一张桌子,但阅读official package summery 总是好的。

    JDK 实际上有 57 个使用 @FunctionalInterface annotation 的接口。以上未提及的包括:

    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);    
    
    */
    

    但是,JDK 有许多接口满足成为没有@FunctionalInterface 注释的功能接口的所有要求(例如AutoClosable)。缺少的注释不会阻止它们作为功能接口工作。它用于在接口违反功能接口的定义时强制编译器抛出错误。在某种程度上,承诺不会扩展您在实现接口时必须覆盖的抽象方法集(可以添加默认方法,因为它们总是有自己的实现)。这让我想知道:why it isn't @FunctionalInterface used on all the interfaces in the JDK that qualify?

    【讨论】:

      【解决方案2】:

      java.util.function 包中一共有 43 个接口。其中 35 个总结在下面的“常规”表格中(由于 StackOverflow 不支持 HTML 表格,因此以明文形式编写):

      General 1
      ---------
      
       ->         Return Type
      |           R                   boolean            void
      V           -                   -------            ----
         T        Function<T,R>       Predicate<T>       Consumer<T>
      P  int      IntFunction<R>      IntPredicate       IntConsumer
      a  long     LongFunction<R>     LongPredicate      LongConsumer
      r  double   DoubleFunction<R>   DoublePredicate    DoubleConsumer
      a  T,U      BiFunction<T,U,R>   BiPredicate<T,U>   BiConsumer<T,U>
      m  void     Supplier<T>         BooleanSupplier    -
      

      General 2
      ---------
      
       ->         Return Type
      |           int                    long                    double
      V           ---                    ----                    ------
         T        ToIntFunction<T>       ToLongFunction<T>       ToDoubleFunction<T>
      P  int      IntUnaryOperator       IntToLongFunction       IntToDoubleFunction
      a  long     LongToIntFunction      LongUnaryOperator       LongToDoubleFunction
      r  double   DoubleToIntFunction    DoubleToLongFunction    DoubleUnaryOperator
      a  T,U      ToIntBiFunction<T,U>   ToLongBiFunction<T,U>   ToDoubleBiFunction<T,U>
      m  void     IntSupplier            LongSupplier            DoubleSupplier
      

      上面“常规”表中未包括的其余 8 个接口是:IntBinaryOperatorLongBinaryOperatorDoubleBinaryOperatorObjIntConsumer&lt;T&gt;ObjLongConsumer&lt;T&gt;ObjDoubleConsumer&lt;T&gt;UnaryOperator&lt;T&gt;BinaryOperator&lt;T&gt;。它们如下表所示。为了便于比较,还显示了相关接口:

      Operators
      ---------
      
       ->                Return Type
      |                  R
      V                  -
         T               Function<T,R>
                         UnaryOperator<T> = Function<T,T>
         T,U             BiFunction<T,U,R>
                         BinaryOperator<T> = BiFunction<T,T,T>
      P
      a                  int
      r                  ---
      a  int             IntUnaryOperator
      m  int,int         IntBinaryOperator
      e
      t                  long
      e                  ----
      r  long            LongUnaryOperator
      s  long,long       LongBinaryOperator
      
                         double
                         ------
         double          DoubleUnaryOperator    
         double,double   DoubleBinaryOperator
      

      Consumers
      ---------
      
       ->           Return Type
      |             void
      V             ----
         T          Consumer<T>
         int        IntConsumer
         long       LongConsumer
      P  double     DoubleConsumer
      a  T,U        BiConsumer<T,U>
      r  T,int      ObjIntConsumer<T>
      a  T,long     ObjLongConsumer<T>
      m  T,double   ObjDoubleConsumer<T>
      

      注意

      • Supplier&lt;T&gt;的类型参数在原源码中是TT是抽象方法的返回类型)。但是,它适合此表中的 R 列,因为它实际上是相同的。

      • 至于完成上表“General 1”的右下角输入,java.lang.Runnable可以认为是void-void接口。

      • UnaryOperator&lt;T&gt;Function&lt;T,T&gt; 的别名(Java 术语中的子接口)。

      • BinaryOperator&lt;T&gt;BiFunction&lt;T,T,T&gt; 的别名(Java 术语中的子接口)

      命名规则

      1. void 作为唯一参数的SAM(单一抽象方法)接口的名称中带有Consumer 后缀;

      2. 返回 void 的 SAM 接口的名称中有 Supplier 后缀;

      3. 返回 boolean 的 SAM 接口的名称中有 Predicate 后缀;

      4. 接受一个参数并返回相同类型的 SAM 接口在其名称中具有 UnaryOperator 后缀;

      5. 接受两个相同类型的参数并返回相同类型的 SAM 接口在其名称中具有 BinaryOperator 后缀;

      6. 所有其他接口的名称中都有Function 后缀;

      7. 带有两个不同类型参数的 SAM 接口在它们的前面有一个 Bi 前缀(如 BiConsumerBiPredicateBiFunction)。

      上表的另一种格式(因为上表在移动设备中可能无法很好地显示):



      P
      一个
      r
      一个



      T
      int
      long
      double
      T,U
      无效
      返回类型
      R
      ------
      函数
      IntFunction
      LongFunction
      DoubleFunction
      BiFunction
      供应商



      P
      一个
      r
      一个



      T
      int
      long
      double
      T,U
      无效
      返回类型
      int
      --------------------
      ToIntFunction
      IntUnaryOperator
      LongToIntFunction
      DoubleToIntFunction
      ToIntBiFunction
      IntSupplier



      P
      一个
      r
      一个



      T
      int
      long
      double
      T,U
      无效
      返回类型
      long
      ---------------------
      ToLongFunction
      IntToLongFunction
      LongUnaryOperator
      DoubleToLongFunction
      ToLongBiFunction
      LongSupplier



      P
      一个
      r
      一个



      T
      int
      long
      double
      T,U
      无效
      返回类型
      double
      ------------------------
      ToDoubleFunction
      IntToDoubleFunction
      LongToDoubleFunction
      DoubleUnaryOperator
      ToDoubleBiFunction
      DoubleSupplier



      P
      一个
      r
      一个



      T
      int
      long
      double
      T,U
      无效
      返回类型
      布尔值
      ----------------
      谓词

      IntPredicate
      LongPredicate
      DoublePredicate
      BiPredicate
      BooleanSupplier



      P
      一个
      r
      一个



      T
      int
      long
      double
      T,U
      无效
      返回类型
      void
      ---------------
      Consumer
      IntConsumer
      LongConsumer
      DoubleConsumer
      BiConsumer
      -

      【讨论】:

      • 你提到了BiSupplier接口,但是JDK中没有这样的接口。此外,根据定义,它会违反真正的功能规范——一个函数接受一个输入,然后返回一个输出。所以,要么你必须从这个接口返回一个元组(这可能是可以接受的),要么你必须有两个 get() 方法,这会很尴尬并且还会违反功能接口规范。因此,我建议您从表中完全删除提及的BiSupplier。除此之外,这是一个非常有用的表格,感谢您的努力。
      • @Quantum 感谢您发现错误。这是一个复制粘贴错误,现在已修复。 :)
      • 我喜欢无滚动条的更新。我会 +1 你,但我已经做到了。 :)
      • @CandiedOrange 非常感谢!其实我也用这张表!所以提高可读性对每个人都有好处:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-12
      • 1970-01-01
      • 2018-09-15
      • 2011-08-08
      • 1970-01-01
      • 2014-08-22
      • 2019-01-15
      相关资源
      最近更新 更多