Java 8: Without Lambda Expression
Java 8: Without Lambda Expression
Java 8: Without Lambda Expression
Java 8 Features
1. Lambda expressions:
1. interface Drawable{
2. public void draw();
3. }
4. public class LambdaExpressionExample {
5. public static void main(String[] args) {
6. int width=10;
7.
8. //without lambda, Drawable implementation using anonymous class
9. Drawable d=new Drawable(){
10. public void draw(){System.out.println("Drawing "+width);}
11. };
12. d.draw();
13. }
14. }
1. interface Sayable{
2. public String say(String name);
3. }
4.
5. public class LambdaExpressionExample4{
6. public static void main(String[] args) {
7.
8. // Lambda expression with single parameter.
9. Sayable s1=(name)->{
10. return "Hello, "+name;
11. };
12. System.out.println(s1.say("Sonoo"));
13.
14. // You can omit function parentheses
15. Sayable s2= name ->{
16. return "Hello, "+name;
17. };
18. System.out.println(s2.say("Sonoo"));
19. }
20. }
1. interface Addable{
2. int add(int a,int b);
3. }
4.
5. public class LambdaExpressionExample5{
6. public static void main(String[] args) {
7.
8. // Multiple parameters in lambda expression
9. Addable ad1=(a,b)->(a+b);
10. System.out.println(ad1.add(10,20));
11.
12. // Multiple parameters with data type in lambda expression
13. Addable ad2=(int a,int b)->(a+b);
14. System.out.println(ad2.add(100,200));
15. }
16. }
1. interface Addable{
2. int add(int a,int b);
3. }
4.
5. public class LambdaExpressionExample6 {
6. public static void main(String[] args) {
7.
8. // Lambda expression without return keyword.
9. Addable ad1=(a,b)->(a+b);
10. System.out.println(ad1.add(10,20));
11.
12. // Lambda expression with return keyword.
13. Addable ad2=(int a,int b)->{
14. return (a+b);
15. };
16. System.out.println(ad2.add(100,200));
17. }
18. }
Java Lambda Expression Example: Foreach Loop
1. import java.util.*;
2. public class LambdaExpressionExample7{
3. public static void main(String[] args) {
4.
5. List<String> list=new ArrayList<String>();
6. list.add("ankit");
7. list.add("mayank");
8. list.add("irfan");
9. list.add("jai");
10.
11. list.forEach(
12. (n)->System.out.println(n)
13. );
14. }
15. }
1. import java.util.ArrayList;
2. import java.util.Collections;
3. import java.util.List;
4. class Product{
5. int id;
6. String name;
7. float price;
8. public Product(int id, String name, float price) {
9. super();
10. this.id = id;
11. this.name = name;
12. this.price = price;
13. }
14. }
15. public class LambdaExpressionExample10{
16. public static void main(String[] args) {
17. List<Product> list=new ArrayList<Product>();
18.
19. //Adding Products
20. list.add(new Product(1,"HP Laptop",25000f));
21. list.add(new Product(3,"Keyboard",300f));
22. list.add(new Product(2,"Dell Mouse",150f));
23.
24. System.out.println("Sorting on the basis of name...");
25.
26. // implementing lambda expression
27. Collections.sort(list,(p1,p2)->{
28. return p1.name.compareTo(p2.name);
29. });
30. for(Product p:list){
31. System.out.println(p.id+" "+p.name+" "+p.price);
32. }
33.
34. }
35. }
Java Lambda Expression Example: Filter Collection Data
1. import java.util.ArrayList;
2. import java.util.List;
3. import java.util.stream.Stream;
4. class Product{
5. int id;
6. String name;
7. float price;
8. public Product(int id, String name, float price) {
9. super();
10. this.id = id;
11. this.name = name;
12. this.price = price;
13. }
14. }
15. public class LambdaExpressionExample11{
16. public static void main(String[] args) {
17. List<Product> list=new ArrayList<Product>();
18. list.add(new Product(1,"Samsung A5",17000f));
19. list.add(new Product(3,"Iphone 6S",65000f));
20. list.add(new Product(2,"Sony Xperia",25000f));
21. list.add(new Product(4,"Nokia Lumia",15000f));
22. list.add(new Product(5,"Redmi4 ",26000f));
23. list.add(new Product(6,"Lenevo Vibe",19000f));
24.
25. // using lambda to filter data
26. Stream<Product> filtered_data = list.stream().filter(p -> p.price > 20000);
27.
28. // using lambda to iterate through collection
29. filtered_data.forEach(
30. product -> System.out.println(product.name+": "+product.price)
31. );
32. }
33. }
3. Reference to a constructor.
1) Reference to a Static Method
You can refer to static method defined in the class. Following is the syntax and example
which describe the process of referring static method in Java.
Syntax
1. ContainingClass::staticMethodName
Example 1
In the following example, we have defined a functional interface and referring a static
method to it's functional method say().
1. interface Sayable{
2. void say();
3. }
4. public class MethodReference {
5. public static void saySomething(){
6. System.out.println("Hello, this is static method.");
7. }
8. public static void main(String[] args) {
9. // Referring static method
10. Sayable sayable = MethodReference::saySomething;
11. // Calling interface method
12. sayable.say();
13. }
14. }
Test it Now
Output:
Example 2
In the following example, we are using predefined functional interface Runnable to refer
static method.
Output:
Thread is running...
Example 3
You can also use predefined functional interface to refer methods. In the following
example, we are using BiFunction interface and using it's apply() method.
1. import java.util.function.BiFunction;
2. class Arithmetic{
3. public static int add(int a, int b){
4. return a+b;
5. }
6. }
7. public class MethodReference3 {
8. public static void main(String[] args) {
9. BiFunction<Integer, Integer, Integer>adder = Arithmetic::add;
10. int result = adder.apply(10, 20);
11. System.out.println(result);
12. }
13. }
Test it Now
Output:
30
Example 4
You can also override static methods by referring methods. In the following example, we
have defined and overloaded three add methods.
1. import java.util.function.BiFunction;
2. class Arithmetic{
3. public static int add(int a, int b){
4. return a+b;
5. }
6. public static float add(int a, float b){
7. return a+b;
8. }
9. public static float add(float a, float b){
10. return a+b;
11. }
12. }
13. public class MethodReference4 {
14. public static void main(String[] args) {
15. BiFunction<Integer, Integer, Integer>adder1 = Arithmetic::add;
16. BiFunction<Integer, Float, Float>adder2 = Arithmetic::add;
17. BiFunction<Float, Float, Float>adder3 = Arithmetic::add;
18. int result1 = adder1.apply(10, 20);
19. float result2 = adder2.apply(10, 20.0f);
20. float result3 = adder3.apply(10.0f, 20.0f);
21. System.out.println(result1);
22. System.out.println(result2);
23. System.out.println(result3);
24. }
25. }
Test it Now
Output:
30
30.0
30.0
Syntax
1. containingObject::instanceMethodName
Example 1
In the following example, we are referring non-static methods. You can refer methods by
class object and anonymous object.
1. interface Sayable{
2. void say();
3. }
4. public class InstanceMethodReference {
5. public void saySomething(){
6. System.out.println("Hello, this is non-static method.");
7. }
8. public static void main(String[] args) {
9. InstanceMethodReference methodReference = new InstanceMethodReferen
ce(); // Creating object
10. // Referring non-static method using reference
11. Sayable sayable = methodReference::saySomething;
12. // Calling interface method
13. sayable.say();
14. // Referring non-static method using anonymous object
15. Sayable sayable2 = new InstanceMethodReference()::saySomething; //
You can use anonymous object also
16. // Calling interface method
17. sayable2.say();
18. }
19. }
Test it Now
Output:
Example 2
In the following example, we are referring instance (non-static) method. Runnable
interface contains only one abstract method. So, we can use it as functional interface.
Example 3
In the following example, we are using BiFunction interface. It is a predefined interface
and contains a functional method apply(). Here, we are referring add method to apply
method.
1. import java.util.function.BiFunction;
2. class Arithmetic{
3. public int add(int a, int b){
4. return a+b;
5. }
6. }
7. public class InstanceMethodReference3 {
8. public static void main(String[] args) {
9. BiFunction<Integer, Integer, Integer>adder = new Arithmetic()::add;
10. int result = adder.apply(10, 20);
11. System.out.println(result);
12. }
13. }
Test it Now
Output:
30
3) Reference to a Constructor
You can refer a constructor by using the new keyword. Here, we are referring
constructor with the help of functional interface.
Syntax
1. ClassName::new
Example:
1. interface Messageable{
2. Message getMessage(String msg);
3. }
4. class Message{
5. Message(String msg){
6. System.out.print(msg);
7. }
8. }
9. public class ConstructorReference {
10. public static void main(String[] args) {
11. Messageable hello = Message::new;
12. hello.getMessage("Hello");
13. }
14. }
Example 1
1. @FunctionalInterface
2. interface sayable{
3. void say(String msg);
4. }
5. public class FunctionalInterfaceExample implements sayable{
6. public void say(String msg){
7. System.out.println(msg);
8. }
9. public static void main(String[] args) {
10. FunctionalInterfaceExample fie = new FunctionalInterfaceExample();
11. fie.say("Hello there");
12. }
13. }
Test it Now
Output:
Hello there
A functional interface can have methods of object class. See in the following example.
Example 2
1.
2. @FunctionalInterface
3. interface sayable{
4. void say(String msg); // abstract method
5. // It can contain any number of Object class methods.
6. int hashCode();
7. String toString();
8. boolean equals(Object obj);
9. }
10. public class FunctionalInterfaceExample2 implements sayable{
11. public void say(String msg){
12. System.out.println(msg);
13. }
14. public static void main(String[] args) {
15. FunctionalInterfaceExample2 fie = new FunctionalInterfaceExample2();
16. fie.say("Hello there");
17. }
18. }
Test it Now
Output:
Hello there
1. interface sayable{
2. void say(String msg); // abstract method
3. }
4. @FunctionalInterface
5. interface Doable extends sayable{
6. // Invalid '@FunctionalInterface' annotation; Doable is not a functional interfac
e
7. void doIt();
8. }
Output:
compile-time error
Example 3
In the following example, a functional interface is extending to a non-functional
interface.
1. interface Doable{
2. default void doIt(){
3. System.out.println("Do it now");
4. }
5. }
6. @FunctionalInterface
7. interface Sayable extends Doable{
8. void say(String msg); // abstract method
9. }
10. public class FunctionalInterfaceExample3 implements Sayable{
11. public void say(String msg){
12. System.out.println(msg);
13. }
14. public static void main(String[] args) {
15. FunctionalInterfaceExample3 fie = new FunctionalInterfaceExample3();
16. fie.say("Hello there");
17. fie.doIt();
18. }
19. }
Java 8 Stream
Java provides a new additional package in Java 8 called java.util.stream. This package
consists of classes, interfaces and enum to allows functional-style operations on the
elements. You can use stream by importing java.util.stream package.
o Stream does not store elements. It simply conveys elements from a source such
as a data structure, an array, or an I/O channel, through a pipeline of
computational operations.
o The elements of a stream are only visited once during the life of a stream. Like an
Iterator, a new stream must be generated to revisit the same elements of the
source.
You can use stream to filter, collect, print, and convert from one data structure to other
etc. In the following examples, we have apply various operations with the help of
stream.
1. import java.util.*;
2. import java.util.stream.Collectors;
3. class Product{
4. int id;
5. String name;
6. float price;
7. public Product(int id, String name, float price) {
8. this.id = id;
9. this.name = name;
10. this.price = price;
11. }
12. }
13. public class JavaStreamExample {
14. public static void main(String[] args) {
15. List<Product> productsList = new ArrayList<Product>();
16. //Adding Products
17. productsList.add(new Product(1,"HP Laptop",25000f));
18. productsList.add(new Product(2,"Dell Laptop",30000f));
19. productsList.add(new Product(3,"Lenevo Laptop",28000f));
20. productsList.add(new Product(4,"Sony Laptop",28000f));
21. productsList.add(new Product(5,"Apple Laptop",90000f));
22. List<Float> productPriceList2 =productsList.stream()
23. .filter(p -> p.price > 30000)// filtering data
24. .map(p->p.price) // fetching price
25. .collect(Collectors.toList()); // collecting as list
26. System.out.println(productPriceList2);
27. }
28. }
Output:
[90000.0]
1. import java.util.stream.*;
2. public class JavaStreamExample {
3. public static void main(String[] args){
4. Stream.iterate(1, element->element+1)
5. .filter(element->element%5==0)
6. .limit(5)
7. .forEach(System.out::println);
8. }
9. }
Output:
5
10
15
20
25
1. import java.util.*;
2. class Product{
3. int id;
4. String name;
5. float price;
6. public Product(int id, String name, float price) {
7. this.id = id;
8. this.name = name;
9. this.price = price;
10. }
11. }
12. public class JavaStreamExample {
13. public static void main(String[] args) {
14. List<Product> productsList = new ArrayList<Product>();
15. //Adding Products
16. productsList.add(new Product(1,"HP Laptop",25000f));
17. productsList.add(new Product(2,"Dell Laptop",30000f));
18. productsList.add(new Product(3,"Lenevo Laptop",28000f));
19. productsList.add(new Product(4,"Sony Laptop",28000f));
20. productsList.add(new Product(5,"Apple Laptop",90000f));
21. // This is more compact approach for filtering data
22. productsList.stream()
23. .filter(product -> product.price == 30000)
24. .forEach(product -> System.out.println(product.name));
25. }
26. }
Output:
Dell Laptop
In the following example, we are using reduce() method, which is used to sum of all the
product prices.
1. import java.util.*;
2. class Product{
3. int id;
4. String name;
5. float price;
6. public Product(int id, String name, float price) {
7. this.id = id;
8. this.name = name;
9. this.price = price;
10. }
11. }
12. public class JavaStreamExample {
13. public static void main(String[] args) {
14. List<Product> productsList = new ArrayList<Product>();
15. //Adding Products
16. productsList.add(new Product(1,"HP Laptop",25000f));
17. productsList.add(new Product(2,"Dell Laptop",30000f));
18. productsList.add(new Product(3,"Lenevo Laptop",28000f));
19. productsList.add(new Product(4,"Sony Laptop",28000f));
20. productsList.add(new Product(5,"Apple Laptop",90000f));
21. // This is more compact approach for filtering data
22. Float totalPrice = productsList.stream()
23. .map(product->product.price)
24. .reduce(0.0f,(sum, price)->sum+price); // accumulating price
25. System.out.println(totalPrice);
26. // More precise code
27. float totalPrice2 = productsList.stream()
28. .map(product->product.price)
29. .reduce(0.0f,Float::sum); // accumulating price, by referring method
of Float class
30. System.out.println(totalPrice2);
31.
32. }
33. }
Output:
201000.0
201000.0
Output:
201000.0
1. import java.util.*;
2. class Product{
3. int id;
4. String name;
5. float price;
6. public Product(int id, String name, float price) {
7. this.id = id;
8. this.name = name;
9. this.price = price;
10. }
11. }
12. public class JavaStreamExample {
13. public static void main(String[] args) {
14. List<Product> productsList = new ArrayList<Product>();
15. //Adding Products
16. productsList.add(new Product(1,"HP Laptop",25000f));
17. productsList.add(new Product(2,"Dell Laptop",30000f));
18. productsList.add(new Product(3,"Lenevo Laptop",28000f));
19. productsList.add(new Product(4,"Sony Laptop",28000f));
20. productsList.add(new Product(5,"Apple Laptop",90000f));
21. // max() method to get max Product price
22. Product productA = productsList.stream()
23. .max((product1, product2)->
24. product1.price > product2.price ? 1: -1).get();
25.
26. System.out.println(productA.price);
27. // min() method to get min Product price
28. Product productB = productsList.stream()
29. .max((product1, product2)->
30. product1.price < product2.price ? 1: -1).get();
31. System.out.println(productB.price);
32.
33. }
34. }
Syntax:
This class provides three different encoders and decoders to encrypt information at each
level. You can use these methods at the following levels.
MIME
It uses the Base64 alphabet as specified in RFC 2045 for encoding and decoding
operations. The encoded output must be represented in lines of no more than 76
characters each and uses a carriage return '\r' followed immediately by a linefeed '\n' as
the line separator. No line separator is added to the end of the encoded output. All line
separators or other characters not found in the base64 alphabet table are ignored in
decoding operation.
Example:
Java provides a facility to create default methods inside the interface. Methods which are
defined inside the interface and tagged with default are known as default methods.
These methods are non-abstract methods.
1. interface Sayable{
2. // Default method
3. default void say(){
4. System.out.println("Hello, this is default method");
5. }
6. // Abstract method
7. void sayMore(String msg);
8. }
9. public class DefaultMethods implements Sayable{
10. public void sayMore(String msg){ // implementing abstract method
11. System.out.println(msg);
12. }
13. public static void main(String[] args) {
14. DefaultMethods dm = new DefaultMethods();
15. dm.say(); // calling default method
16. dm.sayMore("Work is worship"); // calling abstract method
17.
18. }
19. }
This method takes a single parameter which is a functional interface. So, you can pass
lambda expression as an argument.
Singnature:
1. void forEachOrdered(Consumer<? super T> action)
Java Collectors
Collectors is a final class that extends Object class. It provides reduction operations,
such as accumulating elements into collections, summarizing elements according to
various criteria, etc.
Java StringJoiner
Java added a new final class StringJoiner in java.util package. It is used to construct a
sequence of characters separated by a delimiter. Now, you can create string by passing
delimiters like comma(,), hyphen(-) etc. You can also pass prefix and suffix to the char
sequence.
Java Nashorn
Nashorn is a JavaScript engine. It is used to execute JavaScript code dynamically at JVM
(Java Virtual Machine). Java provides a command-line tool jjs which is used to execute
JavaScript code.
You can execute JavaScript code by using jjs command-line tool and by embedding into
Java source code.
Example to execute js code:
Command: jjs hello.js
File: hello.js
1. print("Hello "+name);
File: NashornExample.java
1. import javax.script.*;
2. import java.io.*;
3. public class NashornExample {
4. public static void main(String[] args) throws Exception{
5. // Creating script engine
6. ScriptEngine ee = new ScriptEngineManager().getEngineByName("Nashorn"
);
7. //Binding script and Define scope of script
8. Bindings bind = ee.getBindings(ScriptContext.ENGINE_SCOPE);
9. bind.put("name", "Nashorn");
10. // Reading Nashorn file
11. ee.eval(new FileReader("js/hello.js"));
12. }
13. }
1. print(java.lang.Math.sqrt(4));
Output:
Java Parallel Array Sorting Example: Passing Start and End Index:
1. import java.util.Arrays;
2. public class ParallelArraySorting {
3. public static void main(String[] args) {
4. // Creating an integer array
5. int[] arr = {5,8,1,0,6,9,50,-3};
6. // Iterating array elements
7. for (int i : arr) {
8. System.out.print(i+" ");
9. }
10. // Sorting array elements parallel and passing start, end index
11. Arrays.parallelSort(arr,0,4);
12. System.out.println("\nArray elements after sorting");
13. // Iterating array elements
14. for (int i : arr) {
15. System.out.print(i+" ");
16. }
17. }
18. }
19.
Java provides improved version of type inference in Java 8. the following example
explains, how we can use type inference in our code:
Here, we are creating arraylist by mentioning integer type explicitly at both side. The
following approach is used earlier versions of Java.
In the following declaration, we are mentioning type of arraylist at one side. This
approach was introduce in Java 7. Here, you can left second side as blank diamond and
compiler will infer type of it by type of reference variable.
1. showList(new ArrayList<>());
example:
1. class GenericClass<X> {
2. X name;
3. public void setName(X name){
4. this.name = name;
5. }
6. public X getName(){
7. returnname;
8. }
9. public String genericMethod(GenericClass<String> x){
10. x.setName("John");
11. returnx.name;
12. }
13. }
14.
15. public class TypeInferenceExample {
16. public static void main(String[] args) {
17. GenericClass<String> genericClass = new GenericClass<String>();
18. genericClass.setName("Peter");
19. System.out.println(genericClass.getName());
20.
21. GenericClass<String> genericClass2 = new GenericClass<>();
22. genericClass2.setName("peter");
23. System.out.println(genericClass2.getName());
24.
25. // New improved type inference
26. System.out.println(genericClass2.genericMethod(new GenericClass<>()));
27. }
28. }
1. import java.lang.reflect.Method;
2. import java.lang.reflect.Parameter;
3. public class ParameterReflection {
4. public static void main(String[] args) {
5. // Creating object of a class
6. Calculate calculate = new Calculate();
7. // instantiating Class class
8. Classcls = calculate.getClass();
9. // Getting declared methods inside the Calculate class
10. Method[] method = cls.getDeclaredMethods(); // It returns array of method
s
11. // Iterating method array
12. for (Method method2 : method) {
13. System.out.print(method2.getName()); // getting name of method
14. // Getting parameters of each method
15. Parameter parameter[] = method2.getParameters(); // It returns array o
f parameters
16. // Iterating parameter array
17. for (Parameter parameter2 : parameter) {
18. System.out.print(""+parameter2.getParameterizedType()); // returns
type of parameter
19. System.out.print(""+parameter2.getName()); // returns parameter na
me
20. }
21. System.out.println();
22. }
23. }
24. }
Output:
Above code will produce the below output if you don't use -parameters flag to compile
the Calculate.java file.
Output:
1. @Repeatable(Games.class)
2. @interfaceGame{
3. String name();
4. String day();
5. }
1. @interfaceGames{
2. Game[] value();
3. }
Note - Compiler will throw a compile-time error, if you apply the same annotation to a declaration
without first declaring it as repeatable.
OUTPUT:
Cricket on Sunday
Hockey on Friday
Football on Saturday