面向函数-Function

-Function泛型接口与方法的入口地址

耿祥义

主要内容  1.方法的入口地址 2.得到方法的入口地址 3. Function接口变量

链接(单击阅读阅文也可以下载源代码): 

https://pan.baidu.com/s/1LuyB-Uk99piRhghJbROXEQ 

提取码: hxkj

function在R中的意义_function在R中的意义

1.基本知识点,方法的入口地址

①对象调用实例方法

     当类的字节码文件被加载到内存时,类的实例方法不会被分配入口地址,只有该类创建对象后,类中的实例方法才分配入口地址。

②类名调用类方法(static方法)

    对于类中的类方法,在该类被加载到内存时,就分配了相应的入口地址,类方法可以直接通过类名调用。

function在R中的意义_function在R中的意义

2.得到方法的入口地址

   

JDK8之后,可以类名使用“::”运算符得到该类的静态方法(static方法 )的入口地址,      类名::静态方法 其值的类型属于Function类型。 对象使用“::”运算符得到该类的实例方法的入口地址:     对象::实例方法 其值的类型属于Function类型。 比如,Math类的sqrt方法是static方法,那么     Math::sqrt  就是static方法sqrt的入口地址。 对于String str = new String("ABCD");     str::indexOf  就是实例方法indexOf方法的入口地址。

function在R中的意义_function在R中的意义


 3 Function接口(在java.util.function包)变量


① Function类型


“::”运算符得到方法的入口地址类型是Function类型,因此“::”运算符得到方法的入口地址可以存放到Function接口变量中,例如:   Function funOne = Integer::parseInt;   Function funTwo = Math::sqrt;  Function接口变量声明变量时必须指定泛型T,R代表的具体类型,而且必须和::给出的方法的参数类型和返回类型相匹配。其中T替换成方法的参数类型,R替换成方法的返回类型。int parseInt(String)的参数类型是String类型(用String替换T),返回类型是int(用Integer替换R)。double sqrt(double)参数类型是double类型(用Double替换T),返回类型是double(用Double替换R)。

 ②  R apply(T) 方法

 

  “::”运算符将入口地址放入Function接口变量后,接口变量通过调用apply(T)来使用::”指定的方法,例如     funOne.apply("456") ; 相当于    Integer.parseInt("456");

注  如果方法是2个参数的请参阅Interface BiFunction接口即可。

function在R中的意义_function在R中的意义

4.例子1

function在R中的意义_function在R中的意义_05

下列例子1展示了 Function接口的基本用法。


import java.util.function.Function; 
  public class E1 { 
     public static void main(String args[]) { 
        Function funOne = Integer::parseInt; 
        System.out.println(""+funOne); 
        Integer m = funOne.apply("456") ; 
        System.out.println(m);   
        Function funTwo = Math::sqrt; 
        Double d = funTwo.apply(81.0) ; 
        System.out.println(d);  
        funTwo = Math::cos; 
        d = funTwo.apply(3.1415926) ; 
        System.out.println(d);  
     } 
  }

function在R中的意义_function在R中的意义


5.面向函数

    教材在第5章5.10,讲授了面向抽象的思想。给出的例子,即设计的Pillar类满足开闭原理(柱体计算体积只关心底的面积不必关心它的类型),即系统在增加新的模块时,不需要修改Pillar类的代码。     在这里,例子2中的Pillar类 面向“函数”,即面向Function接口 (面向接口编程的特例)。当系统在增加新的模块时,比如Triangle类负责计算三角形面积,系统不必修改Pillar类。     在某些特殊情况下:方法是一个参数或无参数,系统某个类仅仅依赖方法的返回值,那么就可以面向函数编写该类,使得代码更加简练, 而且还可动态地传递Lambada表达式的值 (Lambada表达式的值是方法的入口地址)给Function接口。例子2中的Pillar面向“函数”,即Function接口。

例子2

function在R中的意义_function函数的用法_07

Pillar.java


import java.util.function.Function; 
  public class Pillar{ 
     double height; 
     Function bottom; 
  //面向“函数” 
     double getVolume(){ 
        double v= bottom.apply(null)*height; 
        return v; 
     } 
     public void setHeight(double height){ 
        this.height =height; 
     } 
      public void setBottom(Function fun){ 
        bottom = fun; 
     } 
  } 
  
E2.java
 
  import java.util.function.Function; 
  public class E2 { 
     public static void main(String args[]) { 
         Pillar pillar = new Pillar(); 
         Rect rect = new Rect(); 
         rect.a = 100; 
         rect.b = 200;  
         pillar.setHeight(10); 
         pillar.setBottom(rect::getArea); 
         double volume=pillar.getVolume(); 
         System.out.println(volume); 
         Circle circle = new Circle(); 
         circle.r = 100; 
         pillar.setHeight(19.9); 
         pillar.setBottom(circle::getArea); 
         volume=pillar.getVolume(); 
         System.out.println(volume); 
         pillar.setBottom((Void)->{ return 2020.0;});//传递Lambada表达式的值 
         volume=pillar.getVolume(); 
         System.out.println(volume); 
     } 
  } 
   
  
Rect.java
 
  public class Rect{ 
     double a,b; 
     public double  getArea(Void v){ 
         return  a*b; 
     } 
  } 
  
Circle.java
 
  public class Circle{ 
     double r; 
     public double getArea(Void v){ 
         return  Math.PI*r*r; 
     } 
  }

function在R中的意义_function在R中的意义