Showing posts with label lambda expression. Show all posts
Showing posts with label lambda expression. Show all posts

Saturday, July 25, 2015

Syntax for Lambda expression in Java

In this article, we try to understand the very basic use of Lambda expression with syntax and many examples. If you want to look what is Lambda and the basic idea behind it, I encourage to read this my article on the basic. I will try to cover all the basic use of Lambda expression in the tutorial.


Syntax for Lambda Expressions
A lambda expression describes an anonymous function. The general syntax for using lambda expressions is very similar to declaring a method. The general syntax is
A lambda expression consists of a list of parameters and a body that are separated by an arrow (->).
The list of parameters is declared the same way as the list of parameters for methods. The list of parameters is enclosed in parentheses, as is done for methods.
The body of a lambda expression is a block of code enclosed in braces. Like a method's body, the body of a lambda expression may declare local variables; use statements including break, continue, and return; throw exceptions, etc.

Unlike a method, a lambda expression does not have four parts.

  1. A lambda expression does not have a name
  2. A lambda expression does not have a return type. It is inferred by the compiler from the context of its use and from its body
  3. A lambda expression does not have a throws clause. It is inferred from the context of its use and its body.
  4. A lambda expression cannot declare type parameters. That is, a lambda expression cannot be generic


Basic example to understand Lambda
Lambda expression are invoked via Function Interface.

Function Interface
A functional interface is simply an interface that has exactly one abstract method. The following types of methods in an interface do not count for defining a functional interface:

  • Default methods
  • Static methods
  • Public methods inherited from the Object class

More detail on Function detail.

Runnable is an example of Function interface, (check Runnable Java 8 doc) so we can use Runnable interface in term of Lambda expression.
Runnable interface method does not take any input and does not return anything. So it lambda expression will look like
() -> {  statements;  }


Example
Similarly, Java 8 has many Functional interface for different purpose. Here is the list of commonly used function interface in the package java.util.function


Following table contains some examples of lambda expressions and equivalent methods. I have given a suitable name to methods as you cannot have a method without a name in Java. The compiler infers the return type of lambda expressions.


Example : how to use above lambda expression with function interface.


One of the goals of the lambda expression was to keep its syntax concise and let the compiler infer the details. The following sections discuss the shorthand syntax for declaring lambda expressions.


Omitting Parameter Types
You can omit the declared type of the parameters. The compiler will infer the types of parameters from the context in which the lambda expression is used

// Types of parameters are declared
(int x, int y) -> { return x + y; }

// Types of parameters are omitted
(x, y) -> { return x + y; }

If you omit the types of parameters, you must omit it for all parameters or for none. You cannot omit for some and not for others. The following lambda expression will not compile because it declares the type of one parameter and omits for the other:

// A compile-time error
(int x, y) -> { return x + y; }


Declaring a Single Parameter
Sometimes a lambda expression takes only one parameter. You can omit the parameter type for a single parameter lambda expression as you can do for a lambda expression with multiple parameters. You can also omit the parentheses if you omit the parameter type in a single parameter lambda expression. The following are three ways to declare a lambda expression with a single parameter:

// Declares the parameter type
(String msg) -> { System.out.println(msg); }

// Omits the parameter type
(msg) -> { System.out.println(msg); }

// Omits the parameter type and parentheses
msg -> { System.out.println(msg); }

The parentheses can be omitted only if the single parameter also omits its type. The following lambda expressionwill not compile:

// Omits parentheses, but not the parameter type, which is not allowed.
String msg -> { System.out.println(msg); }



Declaring No Parameters
If a lambda expression does not take any parameters, you need to use empty parentheses.

// Takes no parameters
() -> { System.out.println("Hello"); }

It is not allowed to omit the parentheses when the lambda expression takes no parameter. The following declaration will not compile:

-> { System.out.println("Hello"); }



Parameters with Modifiers
You can use modifiers, such as final, in the parameter declaration for explicit lambda expressions. The following two lambda expressions are valid:

(final int x, final int y) -> { return x + y; }

(int x, final int y) -> { return x + y; }

The following lambda expression will not compile because it uses the final modifier in parameter declarations, but omits the parameter type:
(final x, final y) -> { return x + y; }


Declaring Body of Lambda Expressions
The body of a lambda expression can be a block statement or a single expression. A block statement is enclosed in braces; a single expression is not enclosed in braces
When a block statement is executed the same way as a method’s body. A return statement or the end of the body returns the control to the caller of the lambda expression.

When an expression is used as the body, it is evaluated and returned to the caller. If the expression evaluates to void, nothing is returned to the caller. The following two lambda expressions are the same; one uses a block statement and the other an expression

// Uses a block statement. Takes two int parameters and returns their sum.
(int x, int y) -> { return x + y; }

// Uses an expression. Takes a two int parameters and returns their sum.
(int x, int y) -> x + y

The following two lambda expressions are the same; one uses a block statement as the body and the other an expression that evaluates to void:

// Uses a block statement
(String msg) -> { System.out.println(msg); }

// Uses an expression
(String msg) -> System.out.println(msg)

Check out this link for more examples



If you know anyone who has started learning Java, why not help them out! Just share this post with them.Thanks for studying today!...

Saturday, March 8, 2014

Flavors of Nested Classes in Java 8

Local|non-local|Static|non-static|anonymous class in Java
In this post, we'll explore varieties nested classes such as static nested classes, inner classes, local inner classes and Anonymous inner class with their pros and cons with examples.

Classes defined within the body of another class (or interface) are known as nested classes. Normally you define a class, which is a top-level class directly belonging to a package. In contrast, nested classes are classes contained within another class or interface.


What is the benefit of creating classes inside another class or interface?
  • You can put related classes together as a single logical group.
  • Nested classes can access all class members of the enclosing class, which might be useful in certain cases.
  • Nested classes are sometimes useful for specific purposes. For example, anonymous inner classes are useful for writing simpler event-handling code with AWT/Swing.
So it worth it to learn it!

There are four types or flavors of nested classes in Java

  • Static nested class
  • Inner class
  • Local inner class
  • Anonymous inner class


The distinction among these 4 classes are not clear at first sight. To understand this, see the representation of four flavors of nested classes schematically.


  • A local class is defined within a code block (whether a method, constructor, or initialization block)
  • A non-local class is defined inside a class.
  • A static class is qualified using the static keyword.
  • A non-static class does not use this static keyword with the class definition.
  • In an anonymous class, you don’t provide the name of the class; you just define its body!



From the diagram, it is clear that :

  • Static nested classes are static and non-local, whereas inner classes are non-static and non-local
  • A non-static and local nested class is a local inner class, and a local and anonymous nested class is an anonymous inner class.

Now let's discuss these class in detail.

Static Nested Classes (or Interfaces)
You'll sometimes hear static nested classes referred to as static inner classes, but they really aren't inner classes at all, by the standard definition of an inner class. While an inner class (regardless of the flavor) enjoys that special relationship with the outer class (or rather the instances of the two classes share a relationship), a static nested class does not.

A static nested class is simply a class that's a static member of the enclosing class:

The class itself isn't really "static"; there's no such thing as a static class.
The static modifier in this case says that the nested class is a static member of the outer class. That means it can be accessed, as with other static members, without having an instance of the outer class.

You can define a class (or interface) as a static member inside another class (or interface). Since the outer type can be a class or an interface and the inner ones can also be a class or interface, there are four combinations.
The following are examples of these four types so that you can see their syntax:
You don’t have to explicitly use the static keyword with a nested interface, since it is implicitly static. Check this post for more detail

Instantiating and Using Static Nested Classes
You use standard syntax to access a static nested class from its enclosing class. The syntax for instantiating a static nested class from a non-enclosing class is a little different from a normal inner class.



Points to Remember about static nested classes
  • The accessibility (public, protected, etc.) of the static nested class is defined by the outer class.
  • A static nested class is not an inner class, it's a top-level nested class.
  • The name of the static nested class is expressed with OuterClassName.NestedClassName syntax.
  • When you define an inner nested class (or interface) inside an interface, the nested class is declared implicitly public and static. This point is easy to remember: any field in an interface is implicitly declared public and static, and static nested classes have this same behavior.Static nested classes can be declared abstract or final.
  • Static nested classes can extend another class or it can be used as a base class.
  • Static nested classes can have static members. 
  • Static nested classes can access the members of the outer class (only static members, obviously).
  • The outer class can also access the members (even private members) of the nested class through an object of nested class. If you don’t declare an instance of the nested class, the outer class cannot access nested class elements directly.



Inner Classes
You can define a class (or an interface) as a non-static member inside another class. How about declaring a class or an interface inside an interface?
As you just saw in the above about static inner classes, when you define a class or an interface inside an interface, it is implicitly static. So, it is not possible to declare a non-static inner interface! That leaves two possibilities:

The outer and inner classes share a special relationship, like friends or members of same family. Member accesses are valid irrespective of the access specifiers such as private. However, there is subtle difference. 
You can access members of an outer class within an inner class without creating an instance; but this is not the case with an outer class. You need to create an instance of inner class in order to access the members (any members, including private members) of the inner class.

One limitation of inner classes is that you cannot declare static members in an inner class, like this


Instantiating an Inner Class
To create an instance of an inner class, you must have an instance of the outer class to tie to the inner class. There are no exceptions to this rule: an inner class instance can never stand alone without a direct relationship to an instance of the outer class

Instantiating an Inner Class from Within the Outer Class

You can see in the preceding code that the Outer code treats Inner just as though Inner were any other accessible class—it instantiates it using the class name (new Inner()), and then invokes a method on the reference variable (inner.go()). But the only reason this syntax works is because the outer class instance method code is doing the instantiating.

Creating an Inner Class Object from Outside the Outer Class Instance Code
If we want to create an instance of the inner class, we must have an instance of the outer class. You already know that, but think about the implications it means that, without a reference to an instance of the outer class, you can't instantiate the inner class from a static method of the outer class because, don't forget, in static code there is no this reference.
Inner class instances are always handed an implicit reference to the outer class. The compiler takes care of it, so you'll never see anything but the end result—the ability of the inner class to access members of the outer class.

Referencing the Inner or Outer Instance from Within the Inner Class
How does an object refer to itself normally? By using the this reference
Quick review of this

  • The keyword this can be used only from within instance code. In other words, not within static code.
  • The this reference is a reference to the currently executing object.
  • The this reference is the way an object can pass a reference to itself to some other code, as a method argument
Within an inner class code, the this reference refers to the instance of the inner class, as you'd probably expect, since this always refers to the currently executing object.
But what if the inner class code wants an explicit reference to the outer class instance that the inner instance is tied to? In other words, how do you reference the "outer this"?
Using reference the "outer this" (the outer class instance) from within the inner class code, use NameOfOuterClass.this 


Points to Remember about Inner class
  • The accessibility (public, protected, etc.) of the inner class is defined by the outer class.
  • Just like top-level classes, an inner class can extend a class or can implement interfaces. Similarly, an inner class can be extended by other classes, and an inner interface can be implemented or extended by other classes or interfaces.
  • An inner class can be declared final or abstract.
  • Inner classes can have inner classes, but you’ll have a hard time reading or understanding such complex nesting of classes.

Member Modifiers Applied to Inner Classes 
A regular inner class is a member of the outer class just as instance variables and methods are, so the following modifiers can be applied to an inner class:

  • final
  • abstract
  • public
  • private
  • private
  • static—but static turns it into a static nested class not an inner class
  • strictfp


Local Inner Classes
A local inner class is defined in a code block (say, in a method, constructor, or initialization block). Unlike static nested classes and inner classes, local inner classes are not members of an outer class; they are just local to the method or code in which they are defined.

As you can see in this code, Local is a class defined within someFunction. It is not available outside of someFunction, not even to the members of the SomeClass. Since you cannot declare a local variable static, you also cannot declare a local class static.

Since you cannot define methods in interfaces, you cannot have local classes or interfaces inside an interface. Nor can you create local interfaces. In other words, you cannot define interfaces inside methods, constructors, and initialization blocks.


This code declare a class Outer with one method go().  But inside go(), another class MethodLocalInner is declared and it has a method of its own. This code is useless ,however, because it never instantiate the inner class! Just because you declared the class doesn't mean you created an instance of it.
So to use the inner class you must make an instance of it somewhere within the method but below the inner class definition. See the next example.


Instantiating method-local inner class
A method-local inner class can be instantiated only within the method where the inner class is defined.
Like regular inner class objects, the method-local inner class object shares a special relationship with the enclosing (outer) class object, and can access its private (or any other) members. However, the inner class object cannot use the local variables of the method the inner class is in. Why not?
The local variables of the method live on the stack, and exist only for the lifetime of the method.
When the method ends, the stack  frame is blown away and the variable is history. But even after the method completes, the inner class object created within it might still be alive on the heap if, for example, a reference to it was passed into some other code and then stored in an instance variable.
Because the local variables aren't guaranteed to be alive as long as the method-local inner class object, the inner class object can't use them. Unless the local variables are marked final !
A local class can have static members provided that they are constant variables


eclipse ex 



However, starting in Java SE 8, a local class can access local variables and parameters of the enclosing block that are final or effectively final. A variable or parameter whose value is never changed after it is initialized is effectively final.
For example, suppose that the variable local_method_variable is not declared final, and you are changing it value then it is effectively final so you can use it in method local inner classes.
But if try to change the value of local_method_variable, then it is no longer effectively final, you get compiler error. Let's see two example:



Points to Remember about method-local inner classes
  • You can create a non-static local class inside a body of code. Interfaces cannot have local  classes, and you cannot create local interfaces.
  • Local classes are accessible only from the body of the code in which the class is defined. The local classes are completely inaccessible outside the body of the code in which the class is defined.
  • You can extend a class or implement interfaces while defining a local class.
  • A local class can access all the variables available in the body of the code in which it is defined. You can pass only final variables to a local inner class.

Shadowing in inner class and method-local inner class
If a declaration of a type (such as a member variable or a parameter name) in a particular scope (such as an inner class or a method definition) has the same name as another declaration in the enclosing scope, then the declaration shadows the declaration of the enclosing scope. You cannot refer to a shadowed declaration by its name alone.

x=10
this.x=10
MyOuter.this.x=0


method variable javalatte
class variable javalatte
Enclosing class var java


Anonymous Inner Classes
As the name implies, an anonymous inner class does not have a name. The declaration of the class automatically derives from the instance-creation expression. They are also referred to simply as anonymous classes.


An anonymous class is useful in almost all situations where you can use local inner classes. A local inner class has a name, whereas an anonymous inner class does not—and that’s the main difference! An additional difference is that an anonymous inner class cannot have any explicit constructors.  A constructor is named after the name of the class, and since an anonymous class has no name, it follows that you cannot define a constructor!
While local classes are class declarations, anonymous classes are expressions, which means that you define the class in another expression

Flavor One creates an anonymous subclass of the specified class type

Flavor two creates an anonymous implementer of the specified interface type


Points to Remember about anonymous classes
  • Anonymous classes are defined in the new expression itself, so you cannot create multiple objects of an anonymous class.
  • You cannot explicitly extend a class or explicitly implement interfaces when defining an anonymous class.
  • An anonymous inner class is always created as part of a statement; don't forget to close the statement after the class definition with a curly brace. This is a rare case in Java, a curly brace followed by a semicolon.
  • Anonymous inner classes have no name, and their type must be either a subclass of the named type or an implementer of the named interface
However, starting in Java SE 8Anonymous classes are used in Lambda expression.


When to Use Nested Classes, Local Classes, Anonymous Classes, and Lambda Expressions

Local class : Use it if you need to create more than one instance of a class, access its constructor, or introduce a new, named type (because, for example, you need to invoke additional methods later).

Anonymous class: Use it if you need to declare fields or additional methods.

Lambda expression:

  • Use it if you are encapsulating a single unit of behavior that you want to pass to other code. For example, you would use a lambda expression if you want a certain action performed on each element of a collection, when a process is completed, or when a process encounters an error.
  • Use it if you need a simple instance of a functional interface and none of the preceding criteria apply (for example, you do not need a constructor, a named type, fields, or additional methods).

Nested class
  • Use it if your requirements are similar to those of a local class, you want to make the type more widely available, and you don't require access to local variables or method parameters.
  • Use a non-static nested class (or inner class) if you require access to an enclosing instance's non-public fields and methods. Use a static nested class if you don't require this access.


If you know anyone who has started learning java, why not help them out! Just share this post with them. 
Thanks for studying today!...