4

我是java新手,我不知道如何编写一个简单的lambda函数。我尝试阅读一些文章,例如这篇文章,但由于出现语法错误,我无法编译。

我希望用F这个代码替换函数λ-function

class Test {
  private int N;
  public Test (int n) {
      N = n;
  }

  private int f (int x) {                   /* <== replace this */
      return 2*x;
  }

  public void print_f () {
      for (int i = 0; i < this.N; i++)
          System.out.println (f(i));        /* <== with lambda here*/
  }

  public static void main (String[] args) {
      int n = 10;
      if (args.length == 1)
          n = Integer.parseInt(args[0]);
      Test t = new Test (n);
      t.print_f ();
  }
}

编辑:我的问题仅涉及Java中λ 函数的语法。不是匿名类的语法。

4

2 回答 2

5

第一个建议是使用 NetBeans,它会教您如何在许多情况下将代码转换为 lambda。在您的特定代码中,您想要转换for (int i = 0;...)一种循环。在 lambda 世界中,您必须将其表示为列表推导,更具体地说,对于 Java,表示为流转换。所以第一步是获取整数流

IntStream.range(0, this.N)

然后对每个成员应用一个 lambda 函数:

IntStream.range(0, this.N).forEach(i->System.out.println(f(i)));

替换您的完整方法print_f如下所示:

public void print_f() {
    IntStream.range(0, this.N).forEach(i->System.out.println(f(i)));
}

print_f但是,在 lambda 的世界中,将其塑造为高阶函数会更自然:

public void print_f(IntConsumer action) {
    IntStream.range(0, this.N).forEach(action);
}

现在您的完整程序将如下所示:

import java.util.function.IntConsumer;
import java.util.stream.IntStream;

class Testing {
    private int N;
    public Testing (int n) {
        N = n;
    }

    private static int f (int x) {
        return 2*x;
    }

    public void print_f(IntConsumer action) {
        IntStream.range(0, this.N).forEach(action);
    }

    public static void main (String[] args) {
        int n = 10;
        if (args.length == 1)
            n = Integer.parseInt(args[0]);
        Testing t = new Testing (n);
        t.print_f(i->System.out.println(f(i)));
    }
}

...好吧,除了一个print_f方法应该真正进行打印并只接受转换函数,这会将您的代码转换为以下内容:

public void print_f(IntFunction f) {
    IntStream.range(0, this.N).forEach(i->System.out.println(f.apply(i)));
}

public static void main (String[] args) {
    int n = 10;
    if (args.length == 1)
        n = Integer.parseInt(args[0]);
    Testing t = new Testing (n);
    t.print_f(Testing::f);
}

...或者,完全消除该f方法,

t.print_f(i->2*i);
于 2013-11-06T10:12:56.657 回答
1

为了回答我自己的问题,使用 Marko Topolnik 提供的答案,这里是一个完整的文件Test.java,它完全符合我的要求,使用原则 Keep It Simple Stupid。

在这种情况下,我从函数λ(int)->int推广到λ(int,int)->int

可以定义的所有可能类型的函数都可以在这里找到:

http://download.java.net/jdk8/docs/api/java/util/function/package-summary.html

import java.util.function.BiFunction;

class Test {
  public static void main (String[] args) {
      int n = 10;
      if (args.length == 1) n = Integer.parseInt(args[0]);
      for (int i=0; i <= n; i++)
          System.out.println (((BiFunction<Integer, Integer, Integer>)
                               (x,y)->2*x+y).apply(i,1));
  }
}

更多示例可以在这里找到:

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html?cid=7180&ssid=105274749521607

于 2013-11-06T16:31:35.383 回答