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

Is it possible to use a specific method of an object (or a static method) as a functor in Java 8

我正在尝试理解 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) 的函数的图示...

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

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

classA 剩下:

 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]);
    }
 }

但是,classB使用了一个函数指针:

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);
 }

希望对您有所帮助...也许有更好的解决方案:-)

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

import static org.junit.Assert.*;
import java.io.UnsupportedEncodingException;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import org.junit.Test;

public class test {

  @Test
  public void java_functions_currying() throws UnsupportedEncodingException {
    A a = new A(1);
    Double[] b = {2d};
    Double[] c = {3d};
    Double[] d = {4d};
    double res = B.g(a::f, b, c, d);
    double res1 = B.g1(a::f1, b, c, d);

    assertEquals(5, res, .01d);
    assertEquals(5, res1, .01d);
  }

  public class A {
    private double a;

    public A(double a) {
      this.a = a;
    }

    // f has type Function<Double[], BiConsumer<Double[], Double[]>>
    // Function<T, R> where 
    // T = Double[]
    // R = BiConsumer<Double[], Double[]>
    public BiConsumer<Double[], Double[]> f(Double[] b) {
      return (c, d) -> d[0] = a * (b[0] + c[0]);
    }

    // f1 has type Function<Double[], Function<Double[], Consumer<Double[]>>>
    // Function<T, R> where 
    // T = Double[]
    // R = Function<Double[], Consumer<Double[]>>
    public Function<Double[], Consumer<Double[]>> f1(Double[] b) {
      return c -> d -> d[0] = a * (b[0] + c[0]);
    }

  }

  public static class B {
    public static double g(Function<Double[], BiConsumer<Double[], Double[]>> funct, Double[] b, Double[] c, Double[] d) {
      funct.apply(b).accept(c, d);
      return d[0];
    }

    public static double g1(Function<Double[], Function<Double[], Consumer<Double[]>>> funct, Double[] b, Double[] c, Double[] d) {
      funct.apply(b).apply(c).accept(d);
      return d[0];
    }
  }
}

方法freturn无效,因此使用Consumerclass是合适的。 消费者接受参数但不接受 return.

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

Java 8 不提供 TriFunction 或 TriConsumer 接口,但这不是必需的。其实连BiFunction和BiConsumer接口都不需要,可以通过Function和Consumer接口创建。

BiFunction<T, U, R>      <=> Function<T Function<U, R>>
BiConsumer<T, U>         <=> Function<T, Consumer<U>
TriFunction<S, T, U, R>  <=> Function<S, Function<T, Function<T, R>>>
TriConsumer<S, T, U>     <=> Function<S, Function<T, Consumer<U>>>

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