3

I am trying to understand functional interfaces in Java 8. Suppose f() to the functor:

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

Is it possible to create a similar construction using the Java 8 functional interface ?

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

In other word,is it possible to use a specific method of the object (or a static method) as a functor? If so, could you give a short example?

The functor represent an illustration of the function working with a data member (a) and some additional parameters (b, c, d )...

4

2 回答 2

0

另一种解决方案是使用现有的 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];
    }
  }
}

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

我添加了两个解决方案。第一个使用接受两个参数的 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>>>

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

于 2016-08-29T10:36:59.197 回答
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);
 }

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

于 2016-08-25T15:37:49.697 回答