Thursday, 31 October 2019

Python Program to Display Prime Numbers

In this post we'll see a Python program to display prime numbers in the given range. This program helps in understanding usage of nested loops and it also shows a use case where for loop with else in Python can be used.

A number is a prime number if it can be divided either by 1 or by the number itself. So every number with in the given range has to be divided in a loop from 2 till number/2 to check if number is a prime number or not. You only need to run your loop from 2 to N/2 (where N is the current number in the passed range), as no number is completely divisible by a number more than its half. Reducing the iteration to N/2 makes your program to display prime numbers more efficient.

Displaying prime numbers Python program

def display_prime(lower, upper):
    for num in range(lower, upper+1):
        # instead of int(num/2), num//2 (floor division) can also be used
        for i in range(2, int(num/2)+1):
            # if number is completely divisible then it
            # it is not a prime number so break out of loop
            if num % i == 0:
                break
        # if loop runs completely that means a prime number
        else:
            print(num)


def get_input():
    """Function to take user input for display range"""
    start = int(input('Enter start number for displaying prime numbers:'))
    end = int(input('Enter end number for displaying prime numbers:'))
    # prime numbers start from 2
    if start <= 1:
        start = 2
    # call function to display prime numbers
    display_prime(start, end)

# start program
get_input()

Output

Enter start number for displaying prime numbers:40
Enter end number for displaying prime numbers:100
41
43
47
53
59
61
67
71
73
79
83
89
97 

That's all for this topic Python Program to Display Prime Numbers. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Python Programs Page


Related Topics

  1. Python Program to Count Occurrences of Each Character in a String
  2. Python Program to Find Factorial of a Number
  3. Keyword Arguments in Python
  4. Name Mangling in Python
  5. Python continue Statement With Examples

You may also like-

  1. Python Exception Handling Tutorial
  2. Method Overriding in Python
  3. Abstract Class in Python
  4. Python String split() Method
  5. getPath(), getCanonicalPath() and getAbsolutePath() Methods in Java
  6. Java Program to Detect And Remove Loop in a Linked List
  7. String And Thread-Safety in Java
  8. Spring MVC File Upload (Multipart Request) Example

Wednesday, 30 October 2019

Serialization and Deserialization in Java

Object serialization is the mechanism of converting object into byte stream. Where as the reverse process of recreating the object from those serialized bytes is known as deserialization. In this post we'll see the process of serialization and deserialization in Java.

Use of serialization in Java

Once an object is converted to a byte stream those bytes can be-

  1. Transmitted from one JVM to another where the object can be reconstituted using those bytes and used in further processing.
  2. Stored on a disk/DB for further use.
Serialization in Java
Serialization in Java

Portability with Java serialization

One important feature of serialization in Java is the portability it offers. When a serialized object is transmitted across the network the serialization mechanism will take into account the differences in operating systems. Thus an object converted into byte streams in Windows OS can be transmitted across the network and deserialized into an object in the Unix operating system.

Requirement for serialization in Java

A mandatory requirement for a class object to be able to be serialized in Java is that the class should implement Serializable interface which is part of java.io package.

Here note that Serializable is a marker interface and does not have any field or method.

Steps for object Serialization in Java

In order to serialize an object in Java you need to do the following-

  • Create an object of ObjectOutputStream.
  • Create an object of OutputStream to be wrapped inside ObjectOutputStream object.
  • Then you need to call writeObject() method which will serialize your object and send it to OutputStream.

Steps for object Deserialization in Java

In order to deserialize an object in Java you need to do the following-

  • Create an object of ObjectInputStream.
  • Create an object of InputStream to be wrapped inside ObjectInputStream object.
  • Then you need to call readObject() method which will reconstitute your object from the byte stream.

Java Serialization and Deserialization example

Let’s see an example of serialization and deserialization in Java, here we have an Address bean with fields like addressline1, city etc. and a Person bean that along with other fields also has an instance of address class. That way you can see that the whole object graph is serialized.

Then we have Util class with the methods to serialize and deserialize an object. Also the test class SerializationDemo to execute the code.

Address class

public class Address implements Serializable{
 private String addressLine1;
 private String addressLine2;
 private String city;
 private String state;
 private String country;
 
 Address(String addressLine1, String addressLine2, String city, String state, String country){
  this.addressLine1 = addressLine1;
  this.addressLine2 = addressLine2;
  this.city = city;
  this.state = state;
  this.country = country;
 }
 public String getAddressLine1() {
  return addressLine1;
 }

 public String getAddressLine2() {
  return addressLine2;
 }
 
 public String getCity() {
  return city;
 }
 
 public String getState() {
  return state;
 }
 
 public String getCountry() {
  return country;
 }
}

Person class

public class Person implements Serializable{

 private static final long serialVersionUID = 1L;
 private String name;
 private Date dob;
 // transient
 private transient int age;
 private Address address;
 // Constructor
 Person(String name, Date dob, int age, Address address){
  System.out.println("In Constructor with args");
  this.name = name;
  this.dob = dob;
  this.age = age;
  this.address = address;
    
 }
 // no-arg Constructor
 Person(){
  System.out.println("no-arg constructor");
 }
 
 public Address getAddress() {
  return address;
 }

 public String getName() {
  return name;
 }
 
 public Date getDob() {
  return dob;
 }
 
 public int getAge() {
  return age;
 }
}

Util class

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Util {
 
 /**
  * Method used for serialization
  * @param obj
  * @param fileName
  */
 public static void serialzeObject(Object obj, String fileName){
  try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
      new File(fileName)))){
   oos.writeObject(obj);
   
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 
 /**
  * Method used for deserializing
  * @param fileName
  * @return
  * @throws ClassNotFoundException
  */
 public static Object deSerialzeObject(String fileName) throws ClassNotFoundException{
  Object obj = null;
  try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(fileName)))){
   obj = ois.readObject();
   
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return obj;
 }

}

SerializationDemo class

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;


public class SerializationDemo {
 public static void main(String[] args) {
  DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
  Date dob = null;
  try {
   dob = df.parse("04/04/2015");
  } catch (ParseException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
  }
  // Creating and initializaing a Address object
  Address address = new Address("#34", "ABC Street", "New Delhi", "Delhi", "India");
  // Creating and initializaing a Person object
  Person person = new Person("User1", dob, 2, address);
  // file name
  final String fileName = "D://person.ser";
  // serializing
  Util.serialzeObject(person, fileName);
  
  try {
   // deserializing
   person = (Person)Util.deSerialzeObject(fileName);
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  System.out.println("deserialized object ---- ");
  System.out.println("Name " + person.getName());
  System.out.println("DOB " + person.getDob());
  System.out.println("Age " + person.getAge());
  System.out.println("Address Line1 " + person.getAddress().getAddressLine1());
  System.out.println("Address Line2 " + person.getAddress().getAddressLine2());
  System.out.println("City " + person.getAddress().getCity());
  System.out.println("State " + person.getAddress().getState());
  System.out.println("Country " + person.getAddress().getCountry());
  
 }
}

Output

In Constructor with args
deserialized object ---- 
Name User1
DOB Sat Apr 04 00:00:00 IST 2015
Age 0
Age #34
Age ABC Street
Age New Delhi
Age Delhi
Age India

In SerializationDemo class you specify the file name and then pass the person object and the file name to the serializeObject method of the Util class which will do the process of serialization. Again you pass the filename which already has the stored bytes for the person object to the deSerializeObject method of the Util class which will deserialize the serialized person object.

Points to note here

  • Here you can see in person object there is a reference to address object and both are serialized which shows the whole object graph gets serialized even if there is a very complex hierarchy.
  • All the classes which are to be serialized should be implementing Serializable interface. In this example suppose Address class doesn’t implement Serializable interface and there is a reference of it in Person class then you will get exception when you try to serialize the person object.
    java.io.NotSerializableException: org.test.Address
  • If you have noticed in Person class there is a system.println in both with args and no-arg constructors. When the object is deserialized you can see even default no-arg constructor is not called. Though reiterated several times I’ll repeat it again that object is reconstituted from the serialized bytes while deserializing and no constructor is called during the process of deserialization.
  • In Person class age field is marked as transient which stops this field from getting serialized. That’s why you can see age is printed as 0.

    Refer Transient in Java to know more about transient keyword.

Implementing writeObject() and readObject() methods

Default mechanism for serialization in Java for us, as end user, is automatic. If you want to have some control over the process of serialization and deserialization in Java then you can implement writeObject() and readObject() methods in your own class.

If you add methods writeObject() and readObject(), these methods will be called automatically when the object is serialized and deserialized respectively and provide the serialization mechanism rather than using the default mechanism.

General form

private void writeObject(ObjectOutputStream oos) throws IOException

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException

writeObject() and readObject() methods - Serialization with inheritance

One scenario where writeObject() and readObject() methods can be used quite effectively is in a parent-child relationship where parent class doesn’t implement the serializable interface but you want the fields that are there in the parent class to be serialized too.

Let’s say we have a classA which is the super class and classB which extends classA.

ClassA

public class ClassA {
 private int deptId;
 private String deptName;
 public int getDeptId() {
  return deptId;
 }
 public void setDeptId(int deptId) {
  this.deptId = deptId;
 }
 public String getDeptName() {
  return deptName;
 }
 public void setDeptName(String deptName) {
  this.deptName = deptName;
 }
 
}

ClassB

import java.io.Serializable;

public class ClassB extends ClassA implements Serializable{
 /**
  * 
  */
 private static final long serialVersionUID = 7280011452607087533L;
 private String empId;
 private String empName;
 public String getEmpId() {
  return empId;
 }
 public void setEmpId(String empId) {
  this.empId = empId;
 }
 public String getEmpName() {
  return empName;
 }
 public void setEmpName(String empName) {
  this.empName = empName;
 }
 
}

In this case if you create a ClassB object and serialize it. Then deserializing it won’t give you any value for the fields which ClassB object gets by virtue of extending ClassA.

public class TestSerialize{
 
 public static void main(String[] args) {
  final String fileName = "D://test.ser";
  ClassB objb = new ClassB();
  objb.setDeptId(1);
  objb.setDeptName("Finance");
  objb.setEmpId("E001");
  objb.setEmpName("Ram");
  Util.serialzeObject(objb, fileName);
  try {
   objb = (ClassB)Util.deSerialzeObject(fileName);
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  System.out.println("DeptId " + objb.getDeptId() + " DeptName " + objb.getDeptName());
  System.out.println("EmpId " + objb.getEmpId() + " EmpName " + objb.getEmpName());
 }

}

Output

DeptId 0 DeptName null
EmpId E001 EmpName Ram

You can see that the deptId and deptName fields which are in ClassA are not serialized as ClassA doesn’t implement Serializable interface.

In this case you will have to add writeObject and readObject methods and provide functionality so that the fields of ClassA are also serialized. So, your updated ClassB with writeObject() and readObject() methods added will look like –

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class ClassB extends ClassA implements Serializable{
 /**
  * 
  */
 private static final long serialVersionUID = 7280011452607087533L;
 private String empId;
 private String empName;
 public String getEmpId() {
  return empId;
 }
 public void setEmpId(String empId) {
  this.empId = empId;
 }
 public String getEmpName() {
  return empName;
 }
 public void setEmpName(String empName) {
  this.empName = empName;
 }
 
 // adding writeObject method
 private void writeObject(ObjectOutputStream oos) throws IOException{
  // calling default functionality for classB fields
  oos.defaultWriteObject();
  // Explicitly writing ClassA fields
  oos.writeInt(getDeptId());
  oos.writeObject(getDeptName());
 }
 
 // adding readObject method
 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
  // calling default functionality for classB fields
  ois.defaultReadObject();
  // Explicitly reading ClassA fields and setting them
  setDeptId(ois.readInt());
  setDeptName((String)ois.readObject());
 }
}

Output

DeptId 1 DeptName Finance
EmpId E001 EmpName Ram

Running it using the TestSerialize class will now give you proper output.

Points to note here

  1. One thing to be careful about here is that the order of reading the fields should be same as the order they were written.
  2. You can use defaultWriteObject() and defaultReadObject() as the first statement in writeObject() and readObject() methods respectively for using the default serialization mechanism.

That's all for this topic Serialization and Deserialization in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Externalizable interface in Java
  2. Transient in Java
  3. serialVersionUID and versioning in Java Serialization
  4. Marker interface in Java
  5. Object Cloning in Java

You may also like -

  1. How ArrayList works internally in Java
  2. Difference between ArrayList and CopyOnWriteArrayList in Java
  3. fail-fast Vs fail-safe iterator in Java
  4. ReentrantReadWriteLock in Java
  5. Spliterator in Java
  6. Lambda expression and exception handling
  7. BigDecimal in Java
  8. String and thread-safety in Java

Keyword Arguments in Python

Generally if you have a function with parameters, while calling the function you pass the arguments in the same positional order. There is also an option of keyword arguments in Python where arguments are passed as key, value pair, since the parameters are identified by their names so keyword arguments are also known as named arguments.

For example here is a function where the positional arguments are passed.

def display_amount(message, amount):
    print(message, '%.2f ' % amount)


display_amount("Total Amount is", 50.56)

Same function with keyword arguments can be written as-

def display_amount(message, amount):
    print(message, '%.2f ' % amount)


display_amount(message="Total Amount is", amount=50.56)

As you can see now the code is more readable though more verbose. With keyword arguments you can even change the position of the arguments as the arguments are identified by name.

def display_amount(message, amount):
    print(message, '%.2f ' % amount)


display_amount(amount=50.56, message="Total Amount is")

Output

Total Amount is 50.56 

Mixing positional arguments with keyword arguments

You can have both positional arguments and keyword arguments in your function call but there is one restriction that positional arguments should come first followed by keyword arguments.

def display_amount(message, amount):
    print(message, '%.2f ' % amount)


display_amount("Total Amount is", amount=50.56)

Output

Total Amount is 50.56 

Not following that order results in error-

def display_amount(message, amount):
    print(message, '%.2f ' % amount)


#display_amount("Total Amount is", amount=50.56)

display_amount(message="Total Amount is", 50.56)
    display_amount(message="Total Amount is", 50.56)
                                             ^
SyntaxError: positional argument follows keyword argument

That's all for this topic Keyword Arguments in Python. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Python Tutorial Page


Related Topics

  1. Python Functions : Returning Multiple Values
  2. Global Keyword in Python With Examples
  3. Local, Nonlocal And Global Variables in Python
  4. Python Conditional Statement - if, elif, else Statements
  5. Convert String to float in Python

You may also like-

  1. Namespace And Variable Scope in Python
  2. Inheritance in Python
  3. Python Program to Find Factorial of a Number
  4. Accessing Characters in Python String
  5. Serialization and Deserialization in Java
  6. java.lang.ClassCastException - Resolving ClassCastException in Java
  7. Linear Search (Sequential Search) Java Program
  8. Spring Boot spring-boot-starter-parent

Tuesday, 29 October 2019

Difference Between Function and Method in Python

If you have started learning Python after working in Java for many years you would have wondered over one thing; while in Java you always call an enclosed group of statements doing a specific task a method, in Python you would have noticed use of both functions and methods. If you think both terms can be used interchangeably then you must know there is a subtle difference between function and method in Python and that’s what is the topic of this post.

Function Vs Method in Python

While both function and methods in Python are written the same way as given below-

def function_name(param1, param2, ..) :
 """function doc string"""
 function suite

How these two differ is that a function in Python is a group of statements that can be written individually in a Python program. You can call that function using its name and passing arguments if any.

A function that is written with in a class and called using an object of the class or using class name is known as method. A method in Python is implicitly passed the object on which it is called using self.

You can understand it this way too, Python can be used to do both procedural as well as object oriented programming. When you are writing a procedural program then you can place common tasks in functions that are called using function name. When you are writing an object oriented program then you use methods to write the logic and call those methods using the objects of the class.

Example of function in Python

def sum(a, b):
    """This function adds the passed values"""
    sum = a + b
    return sum


# calling function
result = sum(5, 6)
print('Sum is', result)

Output

Sum is 11

Here we have a function called sum that takes two arguments and return the sum of those two arguments. You call the function using its name.

Example of method in Python

class Person:
    '''Class Person displaying person information'''
    #class variable
    person_total = 0
    def __init__(self, name, age):
        print('init called')
        self.name = name
        self.age = age
        Person.person_total +=1

    def display(self):
        print(self.name)
        print(self.age)

# printing doc string
print(Person.__doc__)
# creating class instances
person1 = Person('John', 40)
person1.display()
person2 = Person('Lila', 32)
person2.display()
print('Count- ', Person.person_total)

Output

Class Person displaying person information
init called
John
40
init called
Lila
32
Count- 2

That's all for this topic Difference Between Function and Method in Python. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Python Tutorial Page


Related Topics

  1. Passing Object of The Class as Parameter in Python
  2. Python Functions : Returning Multiple Values
  3. Constructor in Python - __init__() function
  4. pass Statement in Python
  5. Local, Nonlocal And Global Variables in Python

You may also like-

  1. Namespace And Variable Scope in Python
  2. Comparing Two Strings in Python
  3. Convert String to int in Python
  4. Python Program to Find Factorial of a Number
  5. Find Minimum and Maximum Value Nodes in Binary Search Tree - Java Program
  6. Invoke Method at Runtime Using Java Reflection API
  7. Difference Between Encapsulation And Abstraction in Java
  8. Spring Integration With Quartz Scheduler

Monday, 28 October 2019

Externalizable Interface in Java

Serialization in Java provides a pretty good default implementation for serializing and deserializing an object. All you need to do is to implement Serializable interface and the whole process is automatic for you.

But, what if you want to control the process of serialization, you have some fields in your object which hold confidential information and you don’t want to serialize those fields or a sub-object with in your object graph doesn’t need to be serialized. That’s when you can use externalizable interface in Java for custom serialization and deserialization.


Externalizable interface in Java

Externalizable interface extends the Serializable interface (which is a marker interface) and adds two methods writeExternal() and readExternal().

When you use Externalizable for your serialization, you will implement Externalizable interface and implement writeExternal() and readExternal() methods. These two methods will be called while serializing and deserializing respectively.

General form of writeExternal() and readExternal()

  • readExternal(ObjectInput in)- The object implements the readExternal method to restore its contents by calling the methods of DataInput for primitive types and readObject for objects, strings and arrays.
  • writeExternal(ObjectOutput out)- The object implements the writeExternal method to save its contents by calling the methods of DataOutput for its primitive values or calling the writeObject method of ObjectOutput for objects, strings, and arrays.

Refer Serialization in Java to see another way, using readObject and writeObject to control the process of serialization.

Serialization process when Externalizable interface is used

Each object to be stored is tested for the Externalizable interface. If the object supports Externalizable, the writeExternal method is called. If the object does not support Externalizable and does implement Serializable, the object is saved using ObjectOutputStream.

When an Externalizable object is reconstructed, an instance is created using the public no-arg constructor, then the readExternal method called. Serializable objects are restored by reading them from an ObjectInputStream.

Externalizable interface Java example

Let’s see an example where we have a class called User in which pwd field is there that you don’t want to convert into bytes. Though that can also be done by marking it as transient but here let us see how Externalizable can be used to control the serialization.

User class

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class User implements Externalizable {
 private String userName;
 private int id;
 private String pwd;
 
 // no-arg constructor **Required**
 public User(){
  System.out.println("In no-arg constructor");
 }
 
 public User(String userName, int id, String pwd){
  System.out.println("In constructor with args");
  this.userName = userName;
  this.id = id;
  this.pwd = pwd;
 }
 
 public String getUserName() {
  return userName;
 }

 public int getId() {
  return id;
 }

 public String getPwd() {
  return pwd;
 }

 @Override
 public void writeExternal(ObjectOutput out) throws IOException {
  System.out.println("In writeExternal method");
  out.writeObject(userName);
  out.writeInt(id);
 }

 @Override
 public void readExternal(ObjectInput in) throws IOException,
   ClassNotFoundException {
  System.out.println("In readExternal method");
  userName = (String)in.readObject();
  id = in.readInt();
 
 }
}

ExternalizableDemo class

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ExternalizableDemo {

 public static void main(String[] args) {
  User user = new User("TestUser", 1, "pwd");
  try {
   ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.ser"));
   oos.writeObject(user);
   oos.close();
   
   ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.ser"));

   user = (User)ois.readObject();
   ois.close();
   System.out.println("UserName " + user.getUserName() + " id " 
      + user.getId() + " pwd " + user.getPwd());
   
  } catch (IOException | ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

Output

In constructor with args
In writeExternal method
In no-arg constructor
In readExternal method
UserName TestUser id 1 pwd null

Here you can see that writeExternal() and readExternal() methods are called for serializing and deserializing the object. Now it is upto you to provide implementation for serialization in writeExternal() method where pwd field is excluded.

Points to note here are-

  1. A default no-arg constructor has to be there while using externalizable as object is created using no-arg constructor while deserializing and then the object is initialized using the logic in readExternal() method. Note that it is different from default serialization where object is reconstituted using the byte stream and constructor is not called.
  2. Order that is used in writeExternal() method for writing the fields should be maintained in readExternal() method.

Externalizable with inheritance

One scenario where Externalizable can be used quite effectively is in a parent-child relationship where parent class doesn’t implement the serializable interface but you want the fields that are there in the parent class to be serialized too.

In this case if you create an object of the child class and serialize it using default serialization. Then deserializing it won’t give you any value for the fields which child class object gets by virtue of extending parent class.

Let’s say we have a classA which is the super class and classB which extends classA.

ClassA

public class ClassA {
  private int deptId;
  private String deptName;
  public int getDeptId() {
   return deptId;
  }
  public void setDeptId(int deptId) {
   this.deptId = deptId;
  }
  public String getDeptName() {
   return deptName;
  }
  public void setDeptName(String deptName) {
   this.deptName = deptName;
  }
}

ClassB

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class ClassB extends ClassA implements Externalizable{
 private String empId;
 private String empName;
 public String getEmpId() {
   return empId;
 }
 public void setEmpId(String empId) {
   this.empId = empId;
 }
 public String getEmpName() {
   return empName;
 }
 public void setEmpName(String empName) {
   this.empName = empName;
 }
 @Override
 public void writeExternal(ObjectOutput out) throws IOException {
  System.out.println("In writeExternal method");
  //Writing parent class ClassA fields
  out.writeInt(getDeptId());
  out.writeObject(getDeptName());
  // Writing child class fields
  out.writeObject(getEmpId());
  out.writeObject(getEmpName());
  
 }

 @Override
 public void readExternal(ObjectInput in) throws IOException,
   ClassNotFoundException {
  System.out.println("In readExternal method");
  // Setting parent class fields
  setDeptId(in.readInt());
  setDeptName((String)in.readObject());
  // Setting child class fields
  setEmpId((String)in.readObject());
  setEmpName((String)in.readObject());
 }

}

Test class

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ExternalizableDemo {

 public static void main(String[] args) {
    final String fileName = "D://test.ser";
    ClassB objb = new ClassB();
    objb.setDeptId(1);
    objb.setDeptName("Finance");
    objb.setEmpId("E001");
    objb.setEmpName("Ram");
  try {
   ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName));
   oos.writeObject(objb);
   oos.close();
   
   ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));

   objb = (ClassB)ois.readObject();
   ois.close();
   System.out.println("DeptId " + objb.getDeptId() + " DeptName " + objb.getDeptName() 
     + " EmpId " + objb.getEmpId() + " EmpName "+ objb.getEmpName());
   
  } catch (IOException | ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

Output

In writeExternal method
In readExternal method
DeptId 1 DeptName Finance EmpId E001 EmpName Ram

Since you can control what is serialized and how, you can make sure that all the fields of super class ClassA are also serialized and deserialized in the writeExternal() and readExternal() methods.

That's all for this topic Externalizable Interface in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. SerialVersionUID And Versioning in Java Serialization
  2. Serialization Proxy Pattern in Java
  3. Marker Interface in Java
  4. Reflection in Java
  5. Object Cloning in Java

You may also like-

  1. How HashSet works internally in Java
  2. Java Collections Interview Questions
  3. Semaphore in Java concurrency
  4. Java Concurrency Interview Questions
  5. Synchronization in Java multithreading
  6. Bounded type parameter in Java generics
  7. Kinds of Variables in Java
  8. Difference Between Checked & Unchecked Exception in Java

Sunday, 27 October 2019

Transient Keyword in Java With Examples

In the post Serialization in Java it has already been discussed that serialization is the mechanism by which any object can be converted to byte stream. By default all of the object variables are converted to bytes and persisted/send across network.

There may be a scenario where you don’t want a variable to be part of serialization because that variable may have some sensitive information which you don’t want to persist or send across the network. That variable can be marked as transient in Java.

Transient keyword in Java

If you want to exclude any object field from getting serialized you can mark that field as transient in Java. Note that you cannot use transient keyword with methods or local variables it can only be used with member variables.

Java transient keyword example

Let’s see an example using transient keyword. Here we have a class called User which has a field pwd which you don’t want to get serialized.

There is a also a class Util that has static methods for serializing and deserializing an object.

User class

import java.io.Serializable;
import java.util.Date;
public class User implements Serializable{
 /**
  * 
  */
 private static final long serialVersionUID = 1L;
 private String userName;
 private Date loginDate;
 // Transient field
 private transient String pwd;
 public String getUserName() {
  return userName;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
 public Date getLoginDate() {
  return loginDate;
 }
 public void setLoginDate(Date loginDate) {
  this.loginDate = loginDate;
 }
 public String getPwd() {
  return pwd;
 }
 public void setPwd(String pwd) {
  this.pwd = pwd;
 }

}

Util class

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Util {
 
 /**
  * Method used for serialization
  * @param obj
  * @param fileName
  */
 public static void serialzeObject(Object obj, String fileName){
  try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
     new File(fileName)))){
   oos.writeObject(obj);
   
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 
 /**
  * Method used for deserializing
  * @param fileName
  * @return
  * @throws ClassNotFoundException
  */
 public static Object deSerialzeObject(String fileName) throws ClassNotFoundException{
  Object obj = null;
  try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
     new File(fileName)))){
   obj = ois.readObject();
   
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return obj;
 }

}

Now let’s create a User object and serialize and deserialize it to see what happens to the pwd field.

import java.util.Date;

public class SerializationDemo {
 public static void main(String[] args) {
  // Creating and initializaing a User object
  User user = getUser();
  // file name
  final String fileName = "D://user.ser";
  // serializing
  Util.serialzeObject(user, fileName);
  
  try {
   // deserializing
   user = (User)Util.deSerialzeObject(fileName);
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  System.out.println("User name " + user.getUserName());
  System.out.println("Login date " + user.getLoginDate());
  System.out.println("Password " + user.getPwd());
  
 }
 
 private static User getUser(){
  User user = new User();
  user.setUserName("TestUser");
  user.setLoginDate(new Date());
  user.setPwd("pwd@123");
  return user;
 }

}

Output

User name TestUser
Login date Mon Apr 03 18:08:49 IST 2017
Password null

If you open the created file “user.ser” you won’t find any trace of pwd variable there.

When to use transient keyword in Java

  1. As mentioned above you can use transient keyword with the variable that holds some confidential value which you don’t want to get persisted in a file or sent across the network.
  2. Any variable that is calculated using other variables can be marked as transient in Java. After deserialization you can get the other variables and recalculate the value. One of the example of this can be found in Java Collection framework itself. In code of HashMap class you can see that hash code is calculated again after deserializing the HashMap key and values. Hashcode is not serialized but recalculated in that case.

    Example code

    Let’s say you have a Person bean where you have both Date Of Birth and age fields. In that case age can be calculated again using the DOB and current date rather than serializing the age. If you are serializing the Person object for long age may be wrong if taken from the deserialized object.

    Person class

    import java.io.Serializable;
    import java.util.Date;
    
    public class Person  implements Serializable{
    
     /**
      * 
      */
     private static final long serialVersionUID = 1L;
     private String name;
     private Date dob;
     // transient
     private transient int age;
     public String getName() {
      return name;
     }
     public void setName(String name) {
      this.name = name;
     }
     public Date getDob() {
      return dob;
     }
     public void setDob(Date dob) {
      this.dob = dob;
     }
     public int getAge() {
      return age;
     }
     public void setAge(int age) {
      this.age = age;
     }
    }
    

    SerializationDemo class

    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.time.LocalDate;
    import java.time.temporal.ChronoUnit;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    
    public class SerializationDemo {
     public static void main(String[] args) {
      // Creating and initializaing a Person object
      Person person = getPerson();
      // file name
      final String fileName = "D://person.ser";
      // serializing
      Util.serialzeObject(person, fileName);
      
      try {
       // deserializing
       person = (Person)Util.deSerialzeObject(fileName);
      } catch (ClassNotFoundException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
      
      System.out.println("Name " + person.getName());
      System.out.println("DOB " + person.getDob());
      System.out.println("Age " + person.getAge());
      
      int age = (int)calculateAge(person);
      System.out.println("age " +age);
     }
     
     /**
      * Method for getting person record
      * @return
      */
     private static Person getPerson(){
      Person person = new Person();
      DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
      try {
       person.setDob(df.parse("04/04/2015"));
      } catch (ParseException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
      person.setName("TestUser");
      return person;
     }
     
     /**
      * Method for calculating age
      * @param person
      * @return
      */
     private static long calculateAge(Person person){
      // creating a calendar instance with DOB
      Calendar firstCal = GregorianCalendar.getInstance();
      firstCal.setTime(person.getDob());
      // Calculating difference in years
      long num = ChronoUnit.YEARS.between( LocalDate.of(firstCal.get(Calendar.YEAR), firstCal.get(Calendar.MONTH), 
         firstCal.get(Calendar.DAY_OF_MONTH)) , LocalDate.now()) ;
      
      return num;
     }
    
    }
    

    Util class is already given above with the serialize() and deserialize() methods.

    Output

    Name TestUser
    DOB Sat Apr 04 00:00:00 IST 2015
    Age 0
    age 2
    
    You can see in the output initially age is 0 after deserialization as age was marked as transient. It’s later calculated using the DOB and current date.
  3. You may have instances that have no meaning if serialized. Like a logger instance, a resource bundle, a properties instance with property values, it's better to mark such instances as transient.

That's all for this topic Transient Keyword in Java With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Externalizable Interface in Java
  2. SerialVersionUID And Versioning in Java Serialization
  3. Serialization Proxy Pattern in Java
  4. Object Cloning in Java
  5. Core Java Basics Interview Questions

You may also like-

  1. How Linked List class works internally in Java
  2. fail-fast Vs fail-safe iterator in Java
  3. Difference Between Comparable and Comparator in Java
  4. Difference Between CountDownLatch And CyclicBarrier in Java
  5. AtomicInteger in Java Concurrency
  6. Race condition in Java multi-threading
  7. Volatile in Java
  8. Type Casting in Java

Saturday, 26 October 2019

Reflection in Java - Getting Constructor Information

Similar to reflection API for methods, there is also reflection API to get information about the constructors of a class. Using java.lang.reflect.Constructor class in Java reflection API you can get information about the modifiers, parameters, annotations, and thrown exceptions. You can also create a new instance of a class using a specified constructor.

How to get Constructor object using reflection

As always the starting point is the Class and there are four methods provided by the class Class for getting the constructors.

  • getConstructor(Class<?>... parameterTypes)- Returns a Constructor object that reflects the specified public constructor of the class represented by this Class object. The parameterTypes parameter is an array of Class objects that identify the constructor's formal parameter types, in declared order.
  • getConstructors()- Returns an array containing Constructor objects reflecting all the public constructors of the class represented by this Class object.
  • getDeclaredConstructor(Class<?>... parameterTypes)– Returns a Constructor object that reflects the specified constructor of the class or interface represented by this Class object. The parameterTypes parameter is an array of Class objects that identify the constructor's formal parameter types, in declared order.
  • getDeclaredConstructors()- Returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object. These are public, protected, default (package) access, and private constructors.

Getting constructor information using reflection Java example

For example we’ll be using this class TestClass which has one public constructor with 2 args and a private constructor.

TestClass.java

public class TestClass {
 private int value;
 private String name;
 // public Constructor
 public TestClass(int value, String name) {
  
  this.value = value;
 }
 // private constructor
 private TestClass() {
  
 }
 
 public void showValue() {
  System.out.println("Value - " + value);
  
 }
}

If you want to get constructors using the above 4 methods it can be done as follows –

import java.lang.reflect.Constructor;
import java.util.Arrays;

public class ReflectConstructor {

 public static void main(String[] args) {
  try {
   Class<?> c = Class.forName("org.prgm.TestClass");
   // To get constructor with 2 args
   Constructor<?> constructor = c.getConstructor(int.class, String.class);
   //Constructor<?> constructor = c.getConstructor(new Class[]{int.class, String.class});
   
   System.out.println("constructor " + constructor.toString());
   // to get private constructor using getDeclaredConstructor() method
   constructor = c.getDeclaredConstructor();
   System.out.println("constructor " + constructor.toString());
   
   // Getting constructors of the class
   Constructor<?>[] constructors = c.getConstructors();
   System.out.println("Constructors - " + Arrays.toString(constructors));
   
   Constructor<?>[] Decconstructors = c.getDeclaredConstructors();
   System.out.println("Declared constructors - " + Arrays.toString(Decconstructors));
  } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }
}

Output

constructor public org.prgm.TestClass(int,java.lang.String)
constructor private org.prgm.TestClass()
Constructors - [public org.prgm.TestClass(int,java.lang.String)]
Declared constructors - [public org.prgm.TestClass(int,java.lang.String), private org.prgm.TestClass()]

Here note that in the first call two parameters are passed with the getConstructor() method which match the arguments of the constructor in the TestClass class. Since parameter is defined as varargs in getConstructor() so you can pass as comma separated parameters or as an array of class objects. Which is done as an illustration in the commented code.

Second call uses the getDeclaredConstructor(); method as that can return constructor object pertaining to private constructor too.

Same way getDeclaredConstructors() method returns an array of Constructor objects reflecting all the constructors of the class public or private where as getConstructors() method returns an array of constructor objects reflecting all the public constructors of the class.

Example code

Class<?> c = Class.forName("org.prgm.TestClass");
Constructor<?>[] Decconstructors = c.getDeclaredConstructors();
for(Constructor<?> ctr : Decconstructors){
 System.out.println("Constructor -- " + ctr.getName());
 Class<?>[] pType  = ctr.getParameterTypes();
 for (int i = 0; i < pType.length; i++) {
  System.out.println("Parameter -- " + pType[i]);
 }
}

Getting modifiers of the constructors using reflection

You can get modifiers of the constructors of the class through reflection using getModifiers() method.

Class<?> c = Class.forName("org.prgm.TestClass");
Constructor<?>[] Decconstructors = c.getDeclaredConstructors();
for(Constructor<?> ctr : Decconstructors){
 System.out.println("Constructor -- " + ctr.getName() + " has modifier " 
  +  Modifier.toString(ctr.getModifiers()));
}

Output

Constructor -- org.prgm.TestClass has modifier public
Constructor -- org.prgm.TestClass has modifier private

Creating class instance using reflection

In reflection API there are two methods for creating instances of classes- java.lang.reflect.Constructor.newInstance() and Class.newInstance(). It is preferable to go with the one provided by the Constructor class for the reasons explained here-

  1. Class.newInstance() can only invoke the zero-argument constructor, while Constructor.newInstance() may invoke any constructor, regardless of the number of parameters.
  2. Class.newInstance() requires that the constructor be visible; Constructor.newInstance() can invoke private constructors also by setting accessibility to true.
  3. Class.newInstance() throws any exception thrown by the constructor whether it is checked or unchecked exception. Constructor.newInstance() always wraps the thrown exception with an InvocationTargetException.

Example code

For the TestClass.java which has one public constructor with two arguments and one no-arg private constructor, creating new class instances can be done as follows.

Class<?> c = Class.forName("org.prgm.TestClass");
Constructor<?>[] Decconstructors = c.getDeclaredConstructors();
for(Constructor<?> ctr : Decconstructors){
 System.out.println("Constructor -- " + ctr.getName());
 try {
  TestClass t;
  if(Modifier.toString(ctr.getModifiers()).equals("private")){
   // Setting accessibility to true if it's a private constructor
   ctr.setAccessible(true);
   t = (TestClass)ctr.newInstance();
  }else{
   t = (TestClass)ctr.newInstance(100, "InstanceTest");
  }   
  t.showValue();
    
 } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
   e.printStackTrace();
 }   
}

Output

Constructor -- org.prgm.TestClass
Value - 100
Constructor -- org.prgm.TestClass
Value – 0

In the code there is a check for the modifier of the constructor. If it is private then the set the accessible flag to true, with that even private constructor can be accessed from another class and an instance created.

That's all for this topic Reflection in Java - Getting Constructor Information. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Reflection in Java - Class
  2. Reflection in Java - Field
  3. Generating Getters And Setters Using Reflection - Java Program
  4. Serialization in Java
  5. Core Java Basics Interview Questions

You may also like-

  1. How ArrayList works internally in Java
  2. TreeSet in Java
  3. ConcurrentHashMap in Java
  4. ReentrantReadWriteLock in Java
  5. Volatile in Java
  6. Lambda expressions in Java 8
  7. Difference between Encapsulation and Abstraction in Java
  8. super in Java

Tuesday, 22 October 2019

Lambda Expression Examples in Java

As we have already seen in the post about Java lambda expressions, they implement the abstract method of the functional interface. In that way lambda expressions can provide a compact and easy to read code which is not repetitive by using them in place of anonymous classes.

Using functional interfaces with anonymous inner classes is a common pattern in Java, from Java 8 lambda expressions provide a better alternative by implementing the abstract method of the functional interface.

In this post we'll see some examples of lambda expressions in Java like Runnable as lambda expression, Comparator as lambda expression, lambda expression implementation of Predicate functional interface.

Runnable as Lambda expression example

It is very common to implement the run method of runnable interface as an anonymous class, now same can be done with lambda expression in fewer lines increasing readability.

public class RunnableLambda {
    public static void main(String[] args) {
        // Runnable using anonymous class
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Runnable with anonymous");
            }
        }).start();
        
        // Runnable using lambda
        new Thread(()->System.out.println("Runnable Lambda")).start();
    }
}

It can be seen how concise the implementation becomes with lambda expression.

Comparator as Lambda expression example

In this example we'll have a list of Person object and they are sorted on first name using Comparator.

Person class

public class Person {
    private String firstName;
    private String lastName;
    private int age;
    private char gender;
    Person(String firstName, String lastName, int age, char gender){
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.gender = gender;
    }
    
    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }
    public char getGender() {
        return gender;
    }
    
    public String toString(){
        StringBuffer sb = new StringBuffer();
        sb.append(getFirstName()).append(" ");
        sb.append(getLastName()).append(" ");
        sb.append(getAge()).append(" ");
        sb.append(getGender());
        return sb.toString();
        
    }
}

// Functional interface
@FunctionalInterface
interface IMyInterface {
    Person getRef(String firstName, String lastName, int age, char gender);
}

public class LambdaExpressionDemo {
    public static void main(String[] args) {
        List<Person> personList = createList();
        
        // comparator implementation as anonymous class
        // and sorting the list element on the basis of first name
        Collections.sort(personList, new Comparator<Person>() {
            public int compare(Person a, Person b) {
                return a.getFirstName().compareTo(b.getFirstName());
             }
        });
        
        System.out.println("Sorted list with anonymous implementation");
        for(Person p : personList){
            System.out.print(p.getFirstName() + " ");
        }
        
        // creating the same list again to use with lambda expression
        personList = createList();
        // Providing the comparator functional interface compare
        /// method as lambda exression
        Collections.sort(personList, (Person a, Person b) -> 
            a.getFirstName().compareTo(b.getFirstName()));
        System.out.println("Sorted list with lambda implementation");
        // Using the new ForEach loop of Java 8 
        // used with lambda expression
        personList.forEach((per) -> System.out.print(per.getFirstName() + " "));
    }
    
    // Utitlity method to create list
    private static List<Person> createList(){
        List<Person> tempList = new ArrayList<Person>();
        IMyInterface createObj = Person::new;
        Person person = createObj.getRef("Ram","Tiwari", 50, 'M');
        tempList.add(person);
        person = createObj.getRef("Prem", "Chopra", 13, 'M');
        tempList.add(person);
        person = createObj.getRef("Tanuja", "Trivedi", 30, 'F');
        tempList.add(person);
        person = createObj.getRef("Manoj", "Sharma", 40, 'M');
        tempList.add(person);
        System.out.println("List elements are - ");
        System.out.println(tempList);
        return tempList;
    }
}

Output

List elements are - 
[Ram Tiwari 50 M, Prem Chopra 13 M, Tanuja Trivedi 30 F, Manoj Sharma 40 M]
Sorted list with anonymous implementation
Manoj Prem Ram Tanuja List elements are - 
[Ram Tiwari 50 M, Prem Chopra 13 M, Tanuja Trivedi 30 F, Manoj Sharma 40 M]
Sorted list with lambda implementation
Manoj Prem Ram Tanuja

Here I have used some of the features of Java 8 like Constructor reference using Double colon operator, which is this line IMyInterface createObj = Person::new;

Also used the new forEach statement in Java 8 with lambda expression, which is this line personList.forEach((per) -> System.out.print(per.getFirstName() + " "));

Same way lambda expression can be used with other functional interfaces like Callable, ActionListener etc.

Lambda expression with inbuilt functional interfaces

With Java 8 many new functional interfaces are being defined, in fact there is a whole new package java.util.function added with many functional interfaces. The interfaces in this package are general purpose functional interfaces used by the JDK, and are available to be used by user code as well.

The following are some of the examples of new functional interfaces in Java 8-

public interface Predicate<T> {
  boolean test(T t);
}
 
public interface Function<T,R> {
  R apply(T t);
}
 
public interface BinaryOperator<T> {
  T apply(T left, T right);
}
 
public interface Consumer<T> {
  void accept(T t);
}
 
public interface Supplier<T> {
  T get();
}

Starting with Java 8 these functional interfaces can be implemented by means of lambda expressions and method references.

We have already seen in the above examples how using lambda expressions we can solve the vertical problem associated with anonymous classes and make the code concise and more readable. Here let's see an example using one of the inbuilt functional interface.

Predicate functional interface as Lambda expression implementation

Supposing we want to use inbuilt functional interface named Predicate declared as follows:

public interface Predicate<T> {
  boolean test(T t);
}

We have a class person and using that person list we want to implement a search criteria where we want to search and print the list of drivers (age >= 16), of voters (age >= 18) and senior citizens (age >= 60). We'll use the inbuilt functional interface Predicate to set up the search criteria. Note that we don’t need to explicitly write the Predicate interface as it is already available, we just need to import it from java.util.function package.

Person Class

public class Person {
    private String firstName;
    private String lastName;
    private int age;
    private char gender;
    public Person(String firstName, String lastName, int age, char gender){
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.gender = gender;
    }
    
    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }
    public char getGender() {
        return gender;
    }
    
    public String toString(){
        StringBuffer sb = new StringBuffer();
        sb.append(getFirstName()).append(" ");
        sb.append(getLastName()).append(" ");
        sb.append(getAge()).append(" ");
        sb.append(getGender());
        return sb.toString();
        
    }
}
@FunctionalInterface
interface IMyFunc {
    Person getRef(String firstName, String lastName, int age, char gender);
}

public class LambdaDemo {
    
    public static void main(String args[])
    {
        List<Person> personList = createList();
        ListPerson listPerson = new ListPerson();
        //Predicates
        // For age >= 16
        Predicate<Person> allDrivers = p -> p.getAge() >= 16;
        // For age >= 18
        Predicate<Person> allVoters = p -> p.getAge() >= 18;
        // For age >= 60
        Predicate<Person> allSeniorCitizens = p -> p.getAge() >= 60;
        // calling method to list drivers, passing predicate as arg
        listPerson.listDrivers(personList, allDrivers);
        
        // calling method to list voters, passing predicate as arg 
        listPerson.listVoters(personList, allVoters);
        
        // calling method to list senior citizens, passing predicate as arg 
        listPerson.listSeniorCitizens(personList, allSeniorCitizens);
        
        
    }
    
     // Utitlity method to create list
     private static List<Person> createList(){
         List<Person> tempList = new ArrayList<Person>();
        // Constructor reference
         IMyFunc createObj = Person::new;
         Person person = createObj.getRef("Ram","Tiwari", 50, 'M');
         tempList.add(person);
         person = createObj.getRef("Prem", "Chopra", 13, 'M');
         tempList.add(person);
         person = createObj.getRef("Tanuja", "Trivedi", 30, 'F');
         tempList.add(person);
         person = createObj.getRef("Manoj", "Sharma", 40, 'M');
         tempList.add(person);
         person = createObj.getRef("John", "Trevor", 70, 'M');
         tempList.add(person);
         person = createObj.getRef("Alicia", "Sliver", 17, 'F');
         tempList.add(person);
         System.out.println("List elements are - ");
         System.out.println(tempList);
         return tempList;
     }
}

class ListPerson {
    // method to list drivers
    public void listDrivers(List<Person> personList, Predicate<Person> pred){
        List<Person> driverList = new ArrayList<Person>();
        for(Person person : personList){
            if (pred.test(person)){
                driverList.add(person);    
            }
        }
        System.out.println("List of drivers ");
        printList(driverList);
    }
    
    // method to list voters
    public void listVoters(List<Person> personList, Predicate<Person> pred){
        List<Person> voterList = new ArrayList<Person>();
        for(Person person : personList){
            if (pred.test(person)){
                voterList.add(person);    
            }
        }
        System.out.println("List of voters ");
        printList(voterList);
    }
    
    // method to list senior citizens
    public void listSeniorCitizens(List<Person> personList, Predicate<Person> pred){
        List<Person> seniorCitizenList = new ArrayList<Person>();
        for(Person person : personList){
            if (pred.test(person)){
                seniorCitizenList.add(person);    
            }
        }
        System.out.println("List of senior citizens ");
        printList(seniorCitizenList);
    }
 
    // Method used for printing the lists
    private void printList(List<Person> personList){
        personList.forEach((p) -> System.out.print(" FirstName - " + p.getFirstName()  
                + " LastName - " + p.getLastName() + " Age - " + p.getAge()));
        System.out.println("");
    }
}

It can be seen how concise and readable the code becomes and it is also non-repetitive, if we were using anonymous classes to write these search criteria we would have done the same chore of taking new instance of interface Predicate and overriding the test method for each search criteria. The anonymous class implementation for getting the list of drivers would have looked like this.

listPerson.listDrivers(personList, new Predicate<Person>(){
   @Override
   public boolean test(Person p){
       return p.getAge() >=16;
   }
});

So it can be seen how lambda expression can help with solving the vertical problem associated with anonymous class and provides a better alternative to provide implementation of functional interfaces.

That's all for this topic Lambda Expression Examples in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Functional Interface Annotation in Java
  2. Method Reference in Java
  3. How to Resolve Local Variable Defined in an Enclosing Scope Must be Final or Effectively Final Error
  4. Lambda Expression And Variable Scope
  5. Java Lambda Expressions Interview Questions

You may also like-

  1. How HashMap Internally Works in Java
  2. Executor and ExecutorService in Java concurrency
  3. final Vs finally Vs finalize
  4. Difference between throw and throws
  5. static method overloading or overriding in Java
  6. covariant return type in Java
  7. effectively final in Java 8
  8. interface default methods in Java 8

Monday, 21 October 2019

How to Resolve Local Variable Defined in an Enclosing Scope Must be Final or Effectively Final Error

This post talks about how to resolve "local variable defined in an enclosing scope must be final or effectively final" error while trying to write a lambda expression in Java.

Let's first get some background on what is effectively final; that will help you to get an idea why this error is coming.

Effectively Final in Java

When a lambda expression uses an assigned local variable from its enclosing space there is an important restriction.
A lambda expression may only use local variable whose value doesn't change. That restriction is referred as "variable capture" which is described as; lambda expression capture values, not variables. The local variables that a lambda expression may use are known as "effectively final".

An effectively final variable is one whose value does not change after it is first assigned. There is no need to explicitly declare such a variable as final, although doing so would not be an error. Since there is no need to explicitly declare such a variable as final thus the name effectively final. If there is an attempt to change such a variable, anyway compiler will throw an error.

Let's see it with an example. Here I have a functional interface IFunc which has a single abstract method display. Since it has a single abstract method it is a functional interface and lambda expression can be used to implement this functional interface. Just to make it clear I have also used the @Functional interface annotation.

In the code lambda expression that implements the display method of the interface just prints the value of the local variable on the console. It can be noted that there is no need to declare variable i as final which was a requirement before Java 8 (in case of anonymous class).

@FunctionalInterface
interface  IFunc{
    void display();
}

public class InnerDemo {
    
    public static void main(String[] args) {
        int i = 7;
        // lambda expression that implements the display method 
        // of the IFunc functional interface 
        IFunc ifunc = ()-> System.out.println("Value of i is " + i);
        // Calling the display method
        ifunc.display();
    }
    
}

Output

Value of i is 7

It can be seen if we are not changing the value of local variable i, it can be used with lambda expression and there is no need to declare i as final.

When will it give error

As already pointed out while discussing effectively final "A lambda expression may only use local variable whose value doesn't change". So if you try to change the value of i with in the lambda expression you'll get the error "Local variable i defined in an enclosing scope must be final or effectively final".

Code that gives compiler error

@FunctionalInterface
interface  IFunc{
    void display();
}

public class InnerDemo {
    public static void main(String[] args) {
        int i = 7;
        // lambda expression that implements the display method 
        // of the IFunc functional interface 
        IFunc ifunc = ()-> System.out.println("Value of i is " + i++);
        // Calling the display method
        ifunc.display();
    }   
}

Here I have changed the i to i++ in System.out thus the program will give compiler error "Local variable i defined in an enclosing scope must be final or effectively final".

So it should be clear by now what it means for a variable to be effectively final and why do you get this error "local variable defined in an enclosing scope must be final or effectively final".

Solution to get around this error

Since it is a rule in Java programming language that variable in an enclosing scope can't be change in inner class or lambda expression, so you can't change the value of the variable. That said, there is a get around which I have used and that get around is to use array.

If we take the previous example again by using an int[] array instead of int variable-

@FunctionalInterface
interface  IFunc{
 void display();
}

public class InnerDemo {
 
 public static void main(String[] args) {
        int[] numArr = {7};
        // lambda expression that implements the display method 
        // of the IFunc functional interface 
        IFunc ifunc = ()-> System.out.println("Value of i is " + (numArr[0]+1));
        // Calling the display method
        ifunc.display();
 }
}

Output

Value of i is 8

As you can see it works now and "local variable defined in an enclosing scope must be final or effectively final" error is not thrown anymore.

Works very well with boolean flags and that's where I have used it. Let's see a small example.

public class Test{
 public static void main(String[] args) {
  List applications = Arrays.asList("A", "B");
  List user = Arrays.asList("A");
  Boolean[] arr = {true}; 
  applications.forEach( a -> {
   for (String str : user) {
    if(a.equals(str)) {
     //error resolved: Local variable flag defined in an enclosing scope must be final or effectively final
     arr[0] = false; 
     break;
    }else{
     arr[0] = true;
    }
   }
 
   if(!arr[0]) {
    System.out.println("Here with false");
   }else{
    System.out.println("Here with true");
   }
  });
 }
}

Output

Here with false
Here with true

Recommendations for learning

  1. Java Programming Masterclass Course
  2. Java In-Depth: Become a Complete Java Engineer!
  3. Spring Framework Master Class Course
  4. Complete Python Bootcamp Course
  5. Python for Data Science and Machine Learning

That's all for this topic How to Resolve Local Variable Defined in an Enclosing Scope Must be Final or Effectively Final Error. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Lambda Expressions in Java 8
  2. Lambda expression and variable scope
  3. How to Fix The Target Type of This Expression Must be a Functional Interface Error
  4. Method Reference in Java
  5. Java Lambda Expressions Interview Questions

You may also like-

  1. Multi-Catch Statement in Java Exception Handling
  2. interface static methods in Java 8
  3. Java Stream API Examples
  4. abstract class in Java
  5. final in Java
  6. ThreadLocal class in Java
  7. How and why to synchronize ArrayList in Java
  8. Best practices for exception handling in Java