This question already has answers here:
Is there a way to compare lambdas?
(3 answers)
Closed 8 years ago.
The following test fails
#Test
public void test() {
Function<String, Integer> foo = Integer::parseInt;
Function<String, Integer> bar = Integer::parseInt;
assertThat(foo, equalTo(bar));
}
is there any way to make it pass?
edit: I'll try to make it more clear what I'm trying to do.
Lets say I have these classes:
class A {
public int foo(Function<String, Integer> foo) {...}
}
class B {
private final A a; // c'tor injected
public int bar() {
return a.foo(Integer::parseInt);
}
}
now lets say i want to write unit test for B:
#Test
public void test() {
A a = mock(A.class);
B b = new B(a);
b.bar();
verify(a).foo(Integer::parseInt);
}
the problem is that the test fails, because the method references are not equal.
Lambdas are not cached and this seems to be deliberate. There is no way to compare two lambdas to see if they would do the same thing.
You need to do something like
static final Function<String, Integer> parseInt = Integer::parseInt;
#Test
public void test() {
Function<String, Integer> foo = parseInt;
Function<String, Integer> bar = parseInt;
assertThat(foo, equalTo(bar));
}
Answer from Brian Goetz; Is there a way to compare lambdas?
I don't have the API at hand, but Function is an interface. Integer::parseInt seems not to cache, so it will return two different instances, which will be compared by reference => false.
You can make it pass by writing a Comparator, which does what you want.
Have look at the Java Language Specification:
15.27.4. Run-time Evaluation of Lambda Expressions
At run time, evaluation of a lambda expression is similar to evaluation of a class instance creation expression, insofar as normal completion produces a reference to an object. Evaluation of a lambda expression is distinct from execution of the lambda body.
Either a new instance of a class with the properties below is allocated and initialized, or an existing instance of a class with the properties below is referenced.
…
These rules are meant to offer flexibility to implementations of the Java programming language, in that:
A new object need not be allocated on every evaluation.
Objects produced by different lambda expressions need not belong to different classes (if the bodies are identical, for example).
Every object produced by evaluation need not belong to the same class (captured local variables might be inlined, for example).
If an "existing instance" is available, it need not have been created at a previous lambda evaluation (it might have been allocated during the enclosing class's initialization, for example).
In principle, this implies that even a single occurrence of Integer::parseInt in your source code may lead to different object instances (even of different classes) when being evaluated multiple times, not to speak of multiple occurrences of it. The exact decision is left to the actual JRE implementation. See this answer discussing the current behavior of Oracle’s implementation.
It's OK that the test doesn't pass. Lambdas are not objects, they are not subject to properties such as object identity. Instead they are adhoc implementations of functional interfaces.
I believe you shouldn't be expecting your code to rely on the behavior you have described.
Related
This question has been previously asked over here
My question regarding why which was answered over here
But I have some doubts about the answer.
The answer provided mentions-
Although other answers prove the requirement, they don't explain why the requirement exists.
The JLS mentions why in §15.27.2:
The restriction to effectively final variables prohibits access to dynamically-changing local variables, whose capture would likely introduce concurrency problems.
To lower the risk of bugs, they decided to ensure captured variables are never mutated.
I am confused by the statement that it would lead to concurrency problems.
I read the article about concurrency problems on Baeldung but still, I am a bit confused about how it will cause concurrency problems, can anybody help me out with an example.
Thanks in advance.
I'd like to preface this answer by saying what I show below is not actually how lambdas are implemented. The actual implementation involves java.lang.invoke.LambdaMetafactory if I'm not mistaken. My answer makes use of some inaccuracies to better demonstrate the point.
Let's say you have the following:
public static void main(String[] args) {
String foo = "Hello, World!";
Runnable r = () -> System.out.println(foo);
r.run();
}
Remember that a lambda expression is shorthand for declaring an implementation of a functional interface. The lambda body is the implementation of the single abstract method of said functional interface. At run-time an actual object is created. So the above results in an object whose class implements Runnable.
Now, the above lambda body references a local variable from the enclosing method. The instance created as a result of the lambda expression "captures" the value of that local variable. It's almost (but not really) like you have the following:
public static void main(String[] args) {
String foo = "Hello, World!";
final class GeneratedClass implements Runnable {
private final String generatedField;
private GeneratedClass(String generatedParam) {
generatedField = generatedParam;
}
#Override
public void run() {
System.out.println(generatedField);
}
}
Runnable r = new GeneratedClass(foo);
r.run();
}
And now it should be easier to see the problems with supporting concurrency here:
Local variables are not considered "shared variables". This is stated in §17.4.1 of the Java Language Specification:
Memory that can be shared between threads is called shared memory or heap memory.
All instance fields, static fields, and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements.
Local variables (§14.4), formal method parameters (§8.4.1), and exception handler parameters (§14.20) are never shared between threads and are unaffected by the memory model.
In other words, local variables are not covered by the concurrency rules of Java and cannot be shared between threads.
At a source code level you only have access to the local variable. You don't see the generated field.
I suppose Java could be designed so that modifying the local variable inside the lambda body only writes to the generated field, and modifying the local variable outside the lambda body only writes to the local variable. But as you can probably imagine that'd be confusing and counterintuitive. You'd have two variables that appear to be one variable based on the source code. And what's worse those two variables can diverge in value.
The other option is to have no generated field. But consider the following:
public static void main(String[] args) {
String foo = "Hello, World!";
Runnable r = () -> {
foo = "Goodbye, World!"; // won't compile
System.out.println(foo);
}
new Thread(r).start();
System.out.println(foo);
}
What is supposed to happen here? If there is no generated field then the local variable is being modified by a second thread. But local variables cannot be shared between threads. Thus this approach is not possible, at least not without a likely non-trivial change to Java and the JVM.
So, as I understand it, the designers put in the rule that the local variable must be final or effectively final in this context in order to avoid concurrency problems and confusing developers with esoteric problems.
When an instance of a lambda expression is created, any variables in the enclosing scope that it refers are copied into it. Now, suppose if that were allowed to modify, and now you are working with a stale value which is there in that copy. On the other hand, suppose the copy is modified inside the lambda, and still the value in the enclosing scope is not updated, leaving an inconsistency. Thus, to prevent such occurrences, the language designers have imposed this restriction. It would probably have made their life easier too. A related answer for an anonymous inner class can be found here.
Another point is that you will be able to pass the lambda expression around and if it is escaped and a different thread executes it, while current thread is updating the same local variable, then there will be some concurrency issues too.
It is for the same reason the anonymous classes require the variables used in their coming out from the scope of themselves must be read-only -> final.
final int finalInt = 0;
int effectivelyFinalInt = 0;
int brokenInt = 0;
brokenInt = 0;
Supplier<Integer> supplier = new Supplier<Integer>() {
#Override
public Integer get() {
return finalInt; // compiles
return effectivelyFinalInt; // compiles
return brokenInt; // doesn't compile
}
};
Lambda expressions are only shortcuts for instances implementing the interface with only one abstract method (#FunctionalInterface).
Supplier<Integer> supplier = () -> brokenInt; // compiles
Supplier<Integer> supplier = () -> brokenInt; // compiles
Supplier<Integer> supplier = () -> brokenInt; // doesn't compile
I struggle to read the Java Language specification to provide support to my statements below, however, they are logical:
Note that evaluation of a lambda expression produces an instance of a functional interface.
Note that instantiating an interface requires implementing all its abstract methods. Doing as an expression produces an anonymous class.
Note that an anonymous class is always an inner class.
Each inner class can access only final or effectively-final variables outside of its scope: Accessing Members of an Enclosing Class
In addition, a local class has access to local variables. However, a local class can only access local variables that are declared final. When a local class accesses a local variable or parameter of the enclosing block, it captures that variable or parameter.
This question already has answers here:
Non-class functions in Java
(4 answers)
Closed 2 years ago.
When declaring methods in Java, do they need to be a part of a class? I am familiar with the idea of a Utility Class:
"Utility Class, also known as Helper class, is a class, which contains just static methods, it is stateless and cannot be instantiated. It contains a bunch of related methods, so they can be reused across the application."
However, can one just create a method separate from any class altogether? (I'd assume scope becomes public by default and declaring anything else for scope might result in an error).
If this is not possible, perhaps that would explain the need for Utility Classes, but I wasn't sure as I hadn't thought about this before - I assumed naturally you could make functions separate from any specific class, but I had been looking through various code samples and couldn't find a specific example where this was occurring.
Part of the reason I am asking this is I was reviewing this article (and mentioned in point 2):
https://www.geeksforgeeks.org/lambda-expressions-java-8/
In it, it states: Lambda expressions are added in Java 8 and provide below functionalities.
1) Enable to treat functionality as a method argument, or code as data.
2) A function that can be created without belonging to any class.
3) A lambda expression can be passed around as if it was an object and executed on demand.
Java is a sort of purely class-based programming language. So, Yes, it and everything needs to be a part of a class.
You are right, you can make a Utility class making methods public static in this way methods can be called without instantiating the class.
Answer to question in the comment:
Why would someone write Object.method() instead of just method()?
Object class is a standard class in java.lang package. You should not create your class named Object otherwise you will need to specify java.lang.Object everywhere you use java.lang.Object.
Now you probably meant
Why would someone write MyUtilClass.method() instead of just method()?
Suppose you have a class MyUtilClass as follows
public class MyUtilClass {
public static int utilMethodA() {
return 1;
}
public static boolean utilMethodB() {
int value = utilMethodA();
if(value == 1)
return true;
else
return false;
}
}
And suppose you have another class MyClass as
public class MyClass {
public void classMethod() {
int value = MyUtilClass.utilMethodA();
}
}
Here if you see in MyUtilClass, utilMethodB() uses utilMethodA() without writing MyUtilClass.utilMethodA() (however, we could write it that way also). Here we did not need to write it as MyUtilClass.utilMethodA() because compiler can find the utilMethodA() without fully specifying it's class because it is present inside it's own class.
Now, In Myclass's myMethod(), we must specify MyUtilClass.utilMethodA() (without it, it won't work), because the compiler has no way of figuring out that you meant to call utilMethodA() of MyUtilClass. There could be hundreds of classes with a method named utilMethodA(), the compiler has no way of finding out which one of the hundred methods you want to call.
Note:-
Also, you can do static import of MyUtilClass.myMethod() like
import static my.package.name.MyUtilClass.myMethodA()
and then use utilMethodA() inside MyClass without prefixing MyUtilClass (but you already informed compile by static import that you will be using utilMethodA() of MyUtilClass right?)
Looks cool to you? No!
This is rather a bad way because
It makes code looks unobvious. In a large class, it may seem that
method utilMethodA() is a local method defined somewhere in
MyClass.
Also, it can generate ambiguity to the compiler if more than one static import of utilMethodA() is done. As compiler has no way of figuring out which of the two you intend to use.
(Edit) Regarding Lambda Expression
Lambda expression is pretty cool stuff added in Java 8. They are basically a kind of function. They provide you the power to define a function right where they need to be used. For example in this link that you provided, see the example shown below syntax of lambda, there the statement
ArrayList<Integer> arrL = new ArrayList<Integer>();
arrL.add(1);
arrL.add(2);
arrL.add(3);
arrL.add(4);
arrL.forEach(n -> { if (n%2 == 0) System.out.println(n); });
Basically, what we are doing here is, we are defining a function, if n is multiple of 2, we print n. We are doing it forEach element of arrL. Did you see, we defined the function to be executed on each element right inside a function call forEach(). That's the beauty of lambda expression.
Now, coming to your question,
So the primary benefit of lambda (besides syntax) is to make it easier to implement functional interfaces (compared to what alternative)?
Yes, sort of. Easy in terms of not creating a separate class implementing the interface and then implementing the abstract method and then calling that implemented method.
This becomes lots of work, especially if you need to call that method only once for example,
Consider the Functional Interface FuncInterface defined as in the link in your question:
interface FuncInterface {
// An abstract function
void abstractFun(int x);
// A non-abstract (or default) function
default void normalFun() {
System.out.println("Hello");
}
}
Now, you want two kind of implementation to your functional interface:
One that provides twice of the passed int x.
Another one that provides square of passed int x.
So, you make two implementations of it:
First FuncInterfaceTwiceImpl
public class FuncInferFaceTwiceImpl implements FuncInterface {
#Override
public void abstractFun(int x) {
System.out.println(2 * x);
}
}
Second, FuncInterfaceSquareImpl as
public class FuncInterfaceSquareImpl implements FuncInterface {
#Override
public void abstractFun(int x) {
System.out.println(x * x);
}
}
Now, you call them as
public class MyClass {
public static void main(String[] args) {
FuncInterface interfaceTwiceObject = new FuncInferFaceTwiceImpl();
interfaceTwiceObject.abstractFun(5);
FuncInterface interfaceSquareObject = new FuncInterfaceSquareImpl();
interfaceSquareObject.abstractFun(5);
}
}
It prints
10
25
Now, what you had to do?
You had to create two separate Classes (in separate new files or
could have made private classes in the same file that of MyClass),
each implementing the abstract method.
Then you instantiated objects of each class and called them
respectively in the main function.
What if this is the only place where you had to call this twice and square thing? You had to make two classes just to use them only once. This effort is too much!!
What if you want to call it without creating new classes and implementing methods in a class?
What if I tell you only provide me the method body, I will do the work for you without you to bother about implementing interface and overriding methods?
Here comes the Lambda magic. Instead of making any impl classes just
head straight towards the main method
Instantiate two objects of FuncInterface providing only method body in Lambda expression.
Call abstract method from objects just like below
public class MyClass {
public static void main(String[] args) {
FuncInterface interfaceTwiceObject = (n) -> System.out.println(2*n);
interfaceTwiceObject.abstractFun(5);
FuncInterface interfaceSquareObject = (n) -> System.out.println(n*n);
interfaceSquareObject.abstractFun(5);
}
}
And boom, the output is
10
25
Just one more time where Lambda saved your day!!
Yes all methods in Java have to be part of a class. You cannot create a method (static or otherwise) which is not associated with a class.
EDIT
Before I answer your question, I will point out that lambda expressions were introduced in Java 8 through the concept of SAM types. In addition, a bit of syntactic sugar was also introduced to facilitate the creation of these types.
When you hear the term "Lambda expression" in Java, you should always remember that they are expressions. Your confusion stems from thinking that lambda expressions evaluate to a pure function not associated with a class or object; well this is simply not the case in Java and I will show you why.
Lambda expressions are not functions
I can now see where your confusion comes from because that article you are reading made a false claim when they say that lambda expression is:
A function that can be created without belonging to any class.
This is simply not true. A lambda expression in Java is not a function. Take the example they give for instance.
interface FuncInterface
{
// An abstract function
void abstractFun(int x);
// A non-abstract (or default) function
default void normalFun()
{
System.out.println("Hello");
}
}
class Test
{
public static void main(String args[])
{
// lambda expression to implement above
// functional interface. This interface
// by default implements abstractFun()
FuncInterface fobj = (int x)->System.out.println(2*x);
// This calls above lambda expression and prints 10.
fobj.abstractFun(5);
}
}
Proof
Now take the comment they have in the main method:
lambda expression to implement above functional interface
From the start they admit that the next line of code implements a functional interface. However functions in Java do not implement interfaces, only classes or other interfaces can do that!
Now, they even go ahead and "call" this function:
This calls above lambda expression and prints 10.
except instead of directly invoking the function (as anyone would if this was really a function), they use the property accessor notation (.) to access the actual method they wanted to call, which means what we have here is not a function, but actually an instance of an anonymous class.
Furthermore, since this object actually contains another method (normalFun), one might ask the question, which one do I use when I want to pass this "function" to another method? This is not a question that is commonly (if ever) asked in the context of lambda functions because there is only one thing to do with a lambda function and that is to call it.
In closing
Java has lambda expressions, not lambda functions.
What makes it a lambda expression is simply the syntactic sugar introduced in Java 8 that uses the () -> { } notation. Unfortunately, many fans of functional programming began associating the term "Lambda function" with objects created using this syntax, and this has led to the confusion you have expressed in your question.
To rehash what I answered previously, all functions in Java are part of a class, and you cannot have a function which is not associated with an object, nor can you create a function outside a class.
HTH
I know about lambda method references.
However, I am wondering whether the reverse might be possible, because I have a method that just proxies its arguments to a lambda:
Function<Arg, Result> lambda = (a) -> new Result(a);
public Result myMethod(Arg arg) {
return lambda.apply(a);
}
Haven't found anything on Google, so I guess it's not possible. Which makes sense, because after all, as I understand it, a lambda is just shorthand for a whole interface. A method and an interface are different. But you can make a lambda from a method, so maybe you can make a method from a lambda?
You can't make a method from a lambda because, as you say, a lambda is not a method and more importantly you cannot dynamically change a class by adding methods to it at runtime. That's a basic design invariant of Java classes. It is possible to dynamically respond to a predefined method of an interface with your own implementation, although it's fairly clunky. Take a look at http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html
The variable lambda has the type Function which doesn’t say anything about how the instance has been created. It might be a lambda expression, but it doesn’t have to. That said, if you want to delegate myMethod to a method declared in Function, there is no reason to automatically choose the abstract method of that interface, so, similar to method references, you would have to specify the target method like lambda::apply to make clear you want that method and not one of the other methods of the interface Function.
But unlike method references, which use a target type, you can’t derive a method declaration from the surrounding context, so you can’t spare the method declaration. So such a hypothetical feature would still require the method declaration, the reference to the lambda field and the target method name (apply), so there is not much left that you can save that would justify a new language feature.
And there is no need for such a functionality anyway. If you have code to be expressed as both, a function and a method, express it as method:
Instead of
Function<Arg, Result> lambda = (a) -> new Result(a);
public Result myMethod(Arg arg) {
return lambda.apply(a);
}
write
Function<Arg, Result> lambda = this::myMethod;
public Result myMethod(Arg arg) {
return new Result(arg);
}
But even a code replication might be acceptable, as in
Function<Arg, Result> lambda = (a) -> new Result(a);
public Result myMethod(Arg arg) {
return new Result(arg);
}
considering that lambda expressions should host rather small, often trivial, code only.
In Java 8 it looks like the lambdas of a class are kept in an array. For example, lets say we have this class:
public class LambdaFactory {
public Supplier<Integer> getOne(){
return () -> 42;
}
public Supplier<Integer> getTwo(){
return () -> 128;
}
public Supplier<Integer> getThree(){
return () -> 3;
}
}
and then I print it out like so:
System.out.println(factory.getOne());
System.out.println(factory.getOne());
System.out.println(factory.getTwo());
System.out.println(factory.getThree());
the output will be something like
examples.LambdaFactory$$Lambda$1#4e515669
examples.LambdaFactory$$Lambda$1#4e515669
examples.LambdaFactory$$Lambda$2#1b9e1916
examples.LambdaFactory$$Lambda$3#ba8a1dc
So we can see two thing here. The same lambda called twice gives us the same lambda object (this is not the same as with anon inner classes where we could get a new one every time). We also see that they look like they are being kept in some kind of "Lambda" structure that is part of the class
My question is, can I get ahold of the lambdas in a class? I don't have any reason to do so, I just like dissecting things
The lambdas are created by the JRE and the way they are created is controlled by the JRE and might vary between different JRE vendors and might change in future versions.
If you want to have fun you can create a lambda at runtime which has no corresponding information within the class file:
import java.lang.invoke.*;
public class ManualLambda {
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup me=MethodHandles.lookup();
MethodType t=MethodType.methodType(void.class);
MethodType rt=MethodType.methodType(Runnable.class);
CallSite site = LambdaMetafactory.metafactory(
me, "run", rt, t, me.findStatic(ManualLambda.class, "sayHello", t), t);
MethodHandle factory=site.getTarget();
Runnable r=(Runnable)factory.invoke();
System.out.println("created lambda: "+r);
r.run();
}
private static void sayHello() {
System.out.println("hello world");
}
}
The code above retraces what happens when a lambda is created. But for compile-time (“real”) lambda expressions the entire thing is triggered by a single invokedynamic byte code instruction. The LambdaMetafactory.metafactory(…) method is the bootstrap method which is called when the invokedynamic instruction is executed the first time. The returned CallSite object is permanently associated with the invokedynamic instruction. If the CallSite is a ConstantCallSite and its MethodHandle returns the same lambda object on every execution, the invokedynamic instruction will “produce” the same lambda instance forever.
The Java Language Specification states
At run time, evaluation of a lambda expression is similar to
evaluation of a class instance creation expression, insofar as normal
completion produces a reference to an object. [...]
Either a new instance of a class with the properties below is
allocated and initialized, or an existing instance of a class with the
properties below is referenced.
[...]
These rules are meant to offer flexibility to implementations of the
Java programming language, in that:
A new object need not be allocated on every evaluation.
[...]
As such, it is up to a compiler or run time environment to decide what should be returned when a lambda expression is evaluated.
My question is, can I get ahold of the lambdas in a class? I don't
have any reason to do so, I just like dissecting things
You can think of a lambda expression as any other class constant, a String, an integer literal, etc. These are constants that appear in the constant pool of a .class file. These are references to objects that are created and exist at run time. There is no way to refer to the actual objects from a class' constant pool.
In the case of a lambda, it wouldn't be helpful anyway because it might not actually be the same object.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can a class have a member of its own type, isnt this infinite recursion?
The Code:
public class Test2{
private Test2 subject = new Test2(); //Create Test2 object in Test2
private int num;
}
The Questions:
Why does Java permit the above code to be executed, but C++ doesn't?
Does the code above create infinite number of objects? Since Test2 itself contains a Test2 object which again contains a Test2 object which itself has a Test2 object and so on.
The key difference between the two languages regarding your problem is that Java is a language with reference semantics (with the exception of primitive types), and C++ a language with value semantics that allows reference semantics through references and pointers.
Syntax that looks similar in both language has complete different meanings, when in Java you create a reference (Test2 x = new Test2();) the equivalent construct in C++ would be using a pointer (Test2 *x = new Test2();).
A key difference is that it is simple to provide reference semantics on top of value semantics through the use of pointers, but it is impossible to provide value semantics on top of (pure) reference semantics. Some of the implications of this statement include not being able to control the layout of objects in Java in memory or the locality of data (for anything other than primitive types and arrays of primitive types), while on the other direction the finer control of objects in C++ allows you to mimic Java objects.
Re question 2 - if you run this code, you get a StackOverflowException => Yes it creates an inifinite number of objects (well it tries...)
public class Test2 {
private Test2 subject = new Test2(); //Create Test2 object in Test2
public static void main(String[] args) throws Exception {
Test2 t = new Test2();
}
}
subject here is a reference to an instance of Test2. If you try to run it, the code will quickly run out of some resource (probably stack space, maybe heap space).
Why does Java permit the above code to be executed but C++ doesn't?
Since 2011, C++ also allows class members to be initalised in their declarations.
However, it wouldn't allow this case: you can only instantiate complete types, and a class type is incomplete within the class definition, so it would have to be initialised in the constructor, or by a call to a function:
class Test;
Test * make_test();
class Test {
// Test is incomplete, so "new Test" is not possible here
Test * test = make_test();
};
// Test is complete, so we can instantiate it here
Test * make_test() {return new Test;}
Java doesn't have a concept of incomplete types, so the class can be instantiated anywhere you're allowed to instantiate any class.
Does the code above create infinite objects?
Yes, trying to instantiate such a class would throw your program into a recursive death spiral.
If you declare subject as being static, you would get an eager initialization version of the Singleton pattern, which will not get you to out of resources.
since you can have multiple constructors its allowed.
if you only have one constructor this would indeed result in an infinite loop.
public class Test{
private Test a;
public Test(String s){
this.a=new Test();
}
public Test(){
}
}