The first recommendation would be to use NetBeans, which will teach you how to transform your code into lambdas in many cases. In your specific code you want to transform a for (int i = 0;...) kind of loop. In the lambda world, you must express this as a list comprehension and more specifically for Java, as a stream transformation. So the first step is to acquire a stream of integers:
IntStream.range(0, this.N)
and then apply a lambda function to each member:
IntStream.range(0, this.N).forEach(i->System.out.println(f(i)));
A complete method which replaces your print_f would look as follows:
public void print_f() {
IntStream.range(0, this.N).forEach(i->System.out.println(f(i)));
}
However, in the world of lambdas it would be more natural to fashion print_f as a higher-order function:
public void print_f(IntConsumer action) {
IntStream.range(0, this.N).forEach(action);
}
And now your complete program would look like this:
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)));
}
}
... well, except that a print_f method should really do the printing and accept only the transformation function, which turns your code into the following:
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);
}
... or, eliminating the f method altogether,
t.print_f(i->2*i);
=>java version "1.8.0-ea"