Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On Java lambda equality and/or instantiation [duplicate]

Why does the snippet below print true on second pass through? Should it not be a new instance?

import java.util.function.Supplier;

public class Foo {
    public static void main(String[] args) throws Exception {
        Supplier<Long> old = () -> System.nanoTime();

        for (int i = 0; i < 3; i++) {
            /* false true true
            Supplier<Long> foo = System::nanoTime;*/

            Supplier<Long> foo = () -> System.nanoTime();

            /* false false false
            Supplier<Long> foo = new Supplier<Long>() {
                @Override
                public Long get() {
                    return System.nanoTime();
                }
            };
            //*/

            System.out.printf("%s %s %s%n", foo == old, foo, old);

            old = foo;
        }
    }
}

false Foo$$Lambda$2/122883338@1ddc4ec2 Foo$$Lambda$1/1534030866@133314b
true Foo$$Lambda$2/122883338@1ddc4ec2 Foo$$Lambda$2/122883338@1ddc4ec2
true Foo$$Lambda$2/122883338@1ddc4ec2 Foo$$Lambda$2/122883338@1ddc4ec2
like image 887
Ilya Kozhevnikov Avatar asked Oct 09 '15 13:10

Ilya Kozhevnikov


People also ask

What are the two important parts of a lambda expression in Java?

A lambda in Java essentially consists of three parts: a parenthesized set of parameters, an arrow, and then a body, which can either be a single expression or a block of Java code.

Can lambda expression be reused?

Fortunately, you can assign lambda expressions to variables and reuse them, as you would with objects.

Does lambda expression improve performance in Java?

Oracle claims that use of lambda expressions also improve the collection libraries making it easier to iterate through, filter, and extract data from a collection. In addition, new concurrency features improve performance in multicore environments.


1 Answers

Check out this article about how lambdas are implemented.

Essentially the compiler turned your two System.nanoTime() into the following static methods on your class:

static Long lambda$1() {
    return System.nanoTime();
}

static Long lambda$2() {
    return System.nanoTime();
}

And then created a constant reference to each target-typed to Supplier<Long> using the LambdaMetaFactory. Frankly, I'm disappointed that the Java compiler didn't realize that the lambda body was identical and only create one instance. If the Java compiler were sufficiently smart, every line should have printed true!

like image 114
sh0rug0ru Avatar answered Oct 20 '22 04:10

sh0rug0ru