是否可以在Java 8中使用对象的特定方法(或静态方法)作为函子

时间:2016-08-25 10:23:18

标签: java java-8 functor functional-interface

我试图理解Java 8中的功能接口。假设f()为仿函数:

public class A {
    private double a;

    public A(double a_) {
        a = a_;
    }

    public void f(double[] b, double[] c, double[] d) {
        d[0] = a * (b[0] + c[0]);
    }
}

是否可以使用Java 8功能界面创建类似的结构?

public class B {
    public double g(Function funct, double[] b, double[] c, double[] d) {
        funct(b, c, d); //Call the functor, minor calculations
        return d[0];
    }

    public static void main(String[] args) {
        A a = new A(1);
        double[] b = {2};
        double[] c = {3};
        double[] d = {4};
        double res = g(a.f, b, c, d);
    }
}

换句话说,是否可以使用对象的特定方法(或静态方法)作为仿函数?如果是这样,你能举一个简短的例子吗?

仿函数表示使用数据成员的函数(a)和一些其他参数(b,c,d)......

2 个答案:

答案 0 :(得分:0)

我找到了以下解决方案。最初,创建接口IFunction:

public interface IFunction {
   double eval(double [] a, double [] b, double [] c) ;
}

A级仍然存在:

 public class A {
    private double a;

    public A(double a_) {a = a_;}

    public void f(double[] b, double[] c, double[] d) {
        d[0] = a * (b[0] + c[0]);
    }
 }

但是,B类使用函数指针:

public class B {

  public double g(IFunction funct, double[] b, double[] c, double[] d) {
    funct.eval(b, c, d);
    return d[0];
  }

  public static void main(String[] args) {
     A a = new A(1);
     double[] b = {2};
     double[] c = {3};
     double[] d = {4};

     double res = g(a::f, b,c, d);
 }

我希望它有所帮助...也许,有一个更好的解决方案: - )

答案 1 :(得分:0)

另一种解决方案是使用现有的java 8接口。

SELECT 
      he.Id,he.Code,he.Name EmployeeName,en.Name [ExamName],bu.Name        
      [Board],[Result] = CASE WHEN 
             ac.GPA IS NULL THEN ac.Result ELSE CAST(ac.GPA AS VARCHAR) END,
      ac.PassingYear 
INTO #Temp 
FROM H_Employee AS he 
INNER JOIN 
      H_AcademicQualification AS ac ON ac.H_EmployeeId = he.Id 
INNER JOIN 
      ExamName AS en ON en.Id = ac.ExamNameId 
INNER JOIN 
      GroupSubject AS gs ON gs.Id = ac.GroupSubjectId 
INNER JOIN 
      BoardUniversity AS bu ON bu.Id = ac.BoardUniversityId

方法f返回void,因此使用Consumer类是合适的。 消费者接受参数但不返回。

我添加了两个解决方案。第一个使用BiConsumer,它接受两个参数。

Java 8不提供TriFunction或TriConsumer接口,但这不是必需的。实际上甚至不需要BiFunction和BiConsumer接口,它们可以通过Function和Consumer接口创建。

SELECT
     a.id, a.Code, a.EmployeeName, a.ExamName, a.Board, a.Result, a.Passingyear, 
     b.ExamName, b.Board, b.Result, b.Passingyear, 
     c.ExamName, c.Board, c.Result, c.Passingyear, 
     d.ExamName, d.Board, d.Result, d.Passingyear 
FROM 
    (SELECT 
          Id, Code, EmployeeName ,ExamName = CASE WHEN 
               ExamName LIKE 'S.S.%' THEN 'S.S.C' END,
          Board=Board ,[Result]=CASE WHEN 
               Result IS NULL THEN Result ELSE CAST(Result AS VARCHAR) END,
          Passingyear 
     FROM #temp 
     WHERE ExamName LIKE 'S.S.%') AS a 
LEFT JOIN 
        (SELECT Id, Code, EmployeeName ,ExamName = CASE WHEN 
            ExamName LIKE 'H.S.%' THEN 'H.S.C' END,
         Board=Board,[Result] = CASE WHEN 
            Result IS NULL THEN Result ELSE CAST(Result AS VARCHAR) END,
         Passingyear  
         FROM #temp 
         WHERE ExamName LIKE 'H.S.%') AS b 
     ON a.Id=b.Id 
LEFT JOIN 
        (SELECT Id, Code, EmployeeName ,ExamName = CASE WHEN 
             ExamName LIKE 'B.%' THEN 'Graduate' END, 
         Board=Board, [Result] = CASE WHEN 
             Result IS NULL THEN Result ELSE CAST(Result AS VARCHAR) END,
         Passingyear 
         FROM #temp 
         WHERE ExamName LIKE 'B.%') AS c 
     ON a.Id=c.Id 
LEFT JOIN 
        (SELECT Id, Code, EmployeeName, ExamName = CASE WHEN
             ExamName LIKE 'M.%' THEN 'Post-Graduate' END, 
         Board=Board,[Result] = CASE WHEN 
             Result IS NULL THEN Result ELSE CAST(Result AS VARCHAR) END,
         Passingyear 
         FROM #temp 
         WHERE ExamName LIKE 'M.%') AS d 
     ON a.Id=d.Id

Search for currying获取有关函数的更多信息,这些函数始终只接受一个参数但返回函数以获取仍然缺少的参数。