4

I am new to java, and I do not know how to write a simple lambda function. I tried to read some articles, like this one, but I do not manage to compile, as I get error of syntax.

I wish to replace the function F is in this code with a λ-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 ();
  }
}

EDIT: My question concerns only the syntax of λ-functions in Java. Not the syntax of anonymous classes.

15
  • Java 8? Other versions do not support lambdas. Commented Nov 6, 2013 at 9:39
  • java -version => java version "1.8.0-ea" Commented Nov 6, 2013 at 9:40
  • And i thought my eyes betray me, "lambdas", "java"? Commented Nov 6, 2013 at 9:41
  • In which case you need to read about Lambda Expressions in Java. You cannot simply pass a function - you need to create a SMI Commented Nov 6, 2013 at 9:42
  • Should I install other development version of java ? It works with this one ? Commented Nov 6, 2013 at 9:43

2 Answers 2

5

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);
Sign up to request clarification or add additional context in comments.

11 Comments

Okay... You used the predefined function type java.util.function.IntFunction. What would you have done if the function you needed had not had a predefined type ?
Trying to compile the first version of the complete program, I get compiling withjavac Test.java && java Test 202 many errors, the first one is: Test.java:18: error: illegal start of expression IntStream.range(0, this.N).forEach(i->System.out.println(f.apply(i)));
I had a messed-up version of code at one point; try now. It compiles and runs for me, build 1.8.0-ea-b108. Be careful with older builds, the Streams API has changed.
If you are using IntStream.forEach, you can't run into the situation where the interface is not predefined because forEach, as well as any other stream-related JDK method, has a definite argument type, and that type by implication already exists.
You run into a situation where you don't have a predefined type only when you code your own library which supports the lambda syntax at the client side. At the library side, there is never a trace of the lambda syntax in method signatures.
|
1

To answer my own question , using the answer provided by Marko Topolnik, here is a complete file Test.java, which does exactly what I asked, using the principle Keep It Simple Stupid.

In this case, I generalized from the function λ(int)->int to λ(int,int)->int.

All possible type of functions that can be defined are found here:

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

Many more examples can be found here:

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

2 Comments

I wouldn't say that java.util.function defines "all possible types of functions." It certainly defines the most common ones. However, we expect that people will one across the need for others. You can simply define your own functional interfaces and use lambdas with them.
Thank you for your comment. If you wish, please edit my message, and tell how can we define the most general type -- but please keep it as simple as possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.