Thursday, March 31, 2022

How to Fix The Target Type of This Expression Must be a Functional Interface Error

This post talks about how to resolve "the target type of this expression must be a functional interface" error while trying to write a lambda expression in Java.

Let's first get some background on what are functional interfaces and lambda expressions in Java; that will help you to get an idea why this error is coming.

Functional Interface in Java

A functional interface is an interface with only one abstract method. A functional interface is also known as SAM type where SAM stands for (Single Abstract Method).

Refer this post to know more about functional interfaces- Functional Interfaces in Java

Lambda expressions in Java

Lambda expression is an instance of the functional interface and provides implementation of the abstract method defined by the functional interface. Thus the functional interface specifies its target type.

Refer this post to know more about lambda expression- Lambda Expressions in Java 8

As you can see Functional interface is an interface with only one abstract method and lambda expression provides implementation of the abstract method defined by the functional interface.

So this error may come when you have a functional interface which has more than one abstract methods. Let's see it with an example. Here I am trying to write a lambda block which counts the number of words in a string.

interface IMyFunc {
  int func(String n);
  int func1(String n1, String n2);
}

public class FuntionalIntError {
  public static void main(String[] args) {
    String inStr = "Lambdas are a new addition to Java";
    // lamda block assigned to a functional interface reference
    IMyFunc myFunc = (str) -> {
      int c = 0;
      char ch[]= new char[str.length()];
      for(int i = 0; i < str.length(); i++){
        ch[i] = str.charAt(i);
        if(((i > 0) && (ch[i] != ' ') && (ch[i-1] == ' ')) || 
            ((ch[0] != ' ') && (i == 0)))
          c++;
      }
      return c;
    };
    // calling the func method of that functional interface 
    System.out.println("The word count is " + myFunc.func(inStr));
  }
}

This code will give me the same error "The target type of this expression must be a functional interface" because of the fact that functional interface IMyFunc has two abstract methods so lambda expression won't know which of these two methods it is implementing and what is its target type.

How to resolve this error

By now you may have guessed that resolving this error "the target type of this expression must be a functional interface" means functional interface should have only one abstract method. So we need to delete the second method.

interface IMyFunc {
  int func(String n);
  //int func1(String n1, String n2);
}

In order to make sure that the functional interface you write has one and only one abstract method, you can use @FunctionalInterface annotation with your functional interface.

 
@FunctionalInterface
interface IMyFunc {
    int func(String n);
}

With this annotation @FunctionalInterface in place, any attempt to add another abstract method to this functional interface will result in compiler error.

That's all for this topic How to Fix The Target Type of This Expression Must be a Functional Interface Error. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Lambda Expression Examples in Java 8
  2. Lambda Expression as Method Parameter
  3. Lambda Expression And Variable Scope
  4. Method Reference in Java
  5. Java Lambda Expressions Interview Questions And Answers

You may also like-

  1. Java Exception Handling Interview Questions And Answers
  2. Java Multithreading Interview Questions And Answers
  3. How HashMap Works Internally in Java
  4. How to Remove Duplicate Elements From an ArrayList in Java
  5. Creating Custom Exception Class in Java
  6. Multi-Catch Statement in Java Exception Handling
  7. super Keyword in Java With Examples
  8. Word Count MapReduce Program in Hadoop

Wednesday, March 30, 2022

Queue Implementation in Java Using Linked List

In this post we’ll see an implementation of Queue in Java using Linked list. Queue can also be implemented using array but that has one drawback; queue size is fixed in that case, which needs some extra work to fill the space created by removing the element from the front.

Queue data structure

A queue is a First In First Out (FIFO) data structure where the first item inserted is the first to be removed. In a queue items are inserted at the rear and removed from the front of the queue.

Following image shows an implementation of Queue as linked list with front and rear references.

Queue Implementation in Java

Operations in a Queue

Mainly following three operations are implemented for a Queue-

  1. insert- To insert an item at the rear of the queue.
  2. remove- To remove an item from the front of the queue.
  3. peek- Read value from the front of the queue without removing it.

Java program for Queue using linked list

For representing nodes of the linked list a separate class (private class Node in the program) is used which apart from the data also holds a reference to itself.

There are also two references front and rear of type Node which are used to point to the first node of the Linked list (front of the queue) and the last node of the Linked list (rear of the queue).

For insert operation new nodes are inserted at the end of the Linked list and the rear points to the new node.

For remove operation first node in the Linked list is removed and the front starts referencing to the next node.

public class LinkedListQueue {
 Node front;
 Node rear;
 public LinkedListQueue(){
  front = null;
  rear = null;
 }
 // Class for node
 private class Node{
  //data
  int i;
  Node next;
  Node(int i){
   this.i = i;
  }
  public void displayData(){
   System.out.println("i= " + i);
  }
 }
 /** Linked list operations, keeping them separate from 
  * Queue operations
  * */
 public void insertLast(int i){
  Node newNode = new Node(i);
  if(isEmpty()){
   front = newNode;
  }else{
   // previous last point to new node
   rear.next = newNode;
  }
  rear = newNode;
 }
 
 public int removeFirst(){  

  int temp = front.i;
  // If no node left after deleting node
  if(front.next == null){
   rear = null;
  }
  // front starts pointing to next element
  front = front.next;
  return temp;
 }
 
 // Method to traverse and display all nodes
 public void displayList(){
  // Start from first node
  Node current = front;
  // loop till last node
  while(current != null){
   current.displayData();
   current = current.next;
  }
 }
 
 public int nodeData(){
  return front.i;
 }
 
 public boolean isEmpty(){
  return front == null;
 }
 /** Queue operations */
 public void insert(int item){
  insertLast(item);
 }
 
 public int remove(){
  if(isEmpty()){
   throw new RuntimeException("Queue is empty..");
  }
  return removeFirst();
 }
 
 public int peek(){
  if(isEmpty()){
   throw new RuntimeException("Queue is empty..");
  }
  return nodeData();
 }
 
 public static void main(String[] args) {
  LinkedListQueue queue = new LinkedListQueue();
  queue.insert(3);
  queue.insert(6);
  System.out.println("-- Displaying Queue data--");
  queue.displayList();
  System.out.println("Item peeked- " + queue.peek());
  System.out.println("-- Removing Queue elements--");
  System.out.println("Item removed- " + queue.remove());
  System.out.println("Item removed- " + queue.remove());
 }
}

Output

-- Displaying Queue data--
i= 3
i= 6
Item peeked- 3
-- Removing Queue elements--
Item removed- 3
Item removed- 6

That's all for this topic Queue Implementation in Java Using Linked List. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Stack Implementation in Java Using Linked List
  2. Doubly Linked List Implementation Java Program
  3. Binary Search Program in Java
  4. Bubble Sort Program in Java
  5. If Given String Sub-Sequence of Another String in Java

You may also like-

  1. Connection Pooling Using C3P0 in Java
  2. Setting And Getting Thread Name And Thread ID in Java
  3. How to Untar a File in Java
  4. Matrix Multiplication Java Program
  5. Thread States (Thread Life Cycle) in Java Multi-Threading
  6. Covariant Return Type in Java
  7. New Date And Time API in Java 8
  8. Automatic Numeric Type Promotion in Java

Tuesday, March 29, 2022

Constructor Overloading in Java

Like method overloading in Java there is also an option to have multiple constructors within the same class where the constructors differ in number and/or types of parameters, that process is known as Constructor overloading in Java. Depending on the parameters the appropriate overloaded constructor is called when the object is created.

Why Constructor overloading is needed

You may need to initialize objects in different ways for that you need different constructors and that is why constructor overloading in Java is needed.

A practical example of constructor overloading in Java would be ArrayList class where there are 2 constructors related to initial capacity.

public ArrayList(int initialCapacity)
public ArrayList() {
  this(10);
}

Monday, March 28, 2022

Encapsulation in Python

Encapsulation is one of the four fundamental OOPS concepts. The other three being Inheritance, Polymorphism, Abstraction

What is Encapsulation

The concept of Encapsulation is to keep together the implementation (code) and the data it manipulates (variables). Having proper encapsulation ensures that the code and data both are safe from misuse by outside entity. That is done by restricting access to the methods and variables and any change to the variables done only through methods.

Encapsulation in Python

In any object oriented language first step towards encapsulation is the class and encapsulation in Python also starts from a class as the class encapsulates the methods and variables. When a Python class is created it contains the methods and the variables. Since it’s the code in the methods that operates on the variables, in a properly encapsulated Python class, methods should define how member variables can be used.

But that’s where the things differ a bit in Python from a language like Java where we have access modifiers like public, private. In Python there are no explicit access modifiers and everything written with in the class (methods and variables) are public by default.

For example in the class Person there are two variables as you can see those variables are accessed through a method as well as directly.

class Person:
  def __init__(self, name, age=0):
    self.name = name
    self.age = age

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

person = Person('John', 40)
#accessing using class method
person.display()
#accessing directly from outside
print(person.name)
print(person.age)

Output

John
40
John
40

Access control in Python

If everything inside a class is public then how to have access control and how to have proper encapsulation in Python?

In Python though there are no explicit access modifiers but using underscores (_) you can make a variable private.

Using single underscore

Using a single leading underscore is merely a convention. A name prefixed with an underscore in Python (as example _name) should be treated as a non-public part of the API (whether it is a function, a method or a data member).

As mentioned it is just a convention and a leading underscore doesn’t actually make any variable or method private or protected. It’s just that if you see a variable or method with a leading underscore in Python code you should follow the convention that it should be used internally with in a class.

For example in class Person if age variable is changed and it is prefixed with underscore.

class Person:
  def __init__(self, name, age=0):
    self.name = name
    self._age = age

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

person = Person('John', 40)
#accessing using class method
person.display()
#accessing directly from outside
print(person.name)
print(person._age)

Output

John
40
John
40

As you can see these variables can still be accessed from outside the class.

Using double underscore (making it private)

If you really want to make a class member (member or variable) private in Python you can do it by prefixing a variable or method with double underscores. Here note that Python provides a limited support for private modifier using a mechanism called name mangling and it is still possible to access such class member from outside the class.

In Python any identifier of the form __var (at least two leading underscores, at most one trailing underscore) is rewritten by the Python interpreter in the form _classname__var, where classname is the current class name. This mechanism of name changing is known as name mangling in Python.

For example in class Person age variable is changed and it is prefixed with two leading underscores.

class Person:
  def __init__(self, name, age=0):
    self.name = name
    self.__age = age

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

person = Person('John', 40)
#accessing using class method
person.display()
#accessing directly from outside
print('Trying to access variables from outside the class ')
print(person.name)
print(person.__age

Output

John
40
Trying to access variables from outside the class
John
Traceback (most recent call last):
  File "Person.py", line 16, in <module>
    print(person.__age)
AttributeError: 'Person' object has no attribute '__age'

As you can see variables can still be accessed using the method which is part of the class but age (which is a private variable) can’t be accessed directly from outside now.

Using getter and setter methods to access private variables

To access and change private variables accessor (getter) methods and mutator (setter methods) should be used which are part of the class.

class Person:
  def __init__(self, name, age=0):
    self.name = name
    self.__age = age

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

  def getAge(self):
    print(self.__age)

  def setAge(self, age):
    self.__age = age

person = Person('John', 40)
#accessing using class method
person.display()
#changing age using setter
person.setAge(45)
person.getAge()

Output

John
40
45

That's all for this topic Encapsulation 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 Installation on Windows
  2. Python First Program - Hello World
  3. Method Overriding in Python
  4. Python for Loop With Examples
  5. Difference Between Function and Method in Python

You may also like-

  1. Constructor in Python - __init__() function
  2. self in Python
  3. Python count() method - Counting Substrings
  4. Python Exception Handling - try,except,finally
  5. How to Read File From The Last Line in Java
  6. Marker Interface in Java
  7. How Linked List class works internally in Java
  8. Race Condition in Java Multi-Threading

Sunday, March 27, 2022

Java Variable Types With Examples

As mentioned in the post object in Java, object is an instance of the class, which gets its state and related behavior from the class. At the same time an object stores its state in variables. So in this post we’ll see types of variables in Java, scopes for those variables in Java and their visibility.

We’ll also see what is meant by declaring a variable and what is meant by initialization of a variable in Java.

Declaring and Initializing a variable in Java

In Java it is mandatory that a variable should be declared before it is used. Declaring a variable means telling what type of a variable it is. Variable may be of primitive data type (int, float, char), or having class or interface as type.

For example

int age, number;

double amount;

Person person;

As you see here in the first statement two variables of type int are declared. Note here that you can declare two or variable of same type as a comma separated list.

In the second statement a variable amount of type double is declared. Where as in third statement a variable person is declared which is of type Person. Here Person is a class.

Java 10 introduced a new feature called local variable type inference where the type of the variable is inferred from the variable initializer. A new reserved type name “var” is added in Java to define and initialize local variables, read more about var type here- Var type in Java - Local Variable Type Inference

Initialization of a variable in Java

Initialization means providing initial value of the variable. Generally, both declaration and initialization are done in a single statement.

 
int age = 30;

char a = ‘A’;

But that is not necessary you may declare a variable first and initialize it later.

 
int age;

...... 
......
age = 50;

An expression can also be used to initialize a variable -

 
double amount;

amount = 67/9;

Here amount will have the value of 67 divided by 9.

Types of variables in Java

The Java programming language defines the following kinds of variables:

  1. Instance Variables (Non-Static Fields)– As already mentioned object is an instance of the class and there can be many objects of the same class. Every object has its own state for the non-static fields which is unique for each instance (object). That is why the fields of each object are referred as instance variables as they are unique for each instance.

    For example, if you have a class Person and two objects of it person1 and person2 then the instance variables of these two objects will have independent values.

    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 class InstanceDemo {
    
     public static void main(String[] args) {
      Person person1 = new Person("Ram", "Mishra", 23, 'M');
      Person person2 = new Person("Amita", "Chopra", 21, 'F');
      
      System.out.println("Values in object person1 - " + 
        person1.getAge() + " " + person1.getFirstName() + " " + 
        person1.getLastName()+ " " + person1.getGender());
      System.out.println("Values in object person2 - " + 
        person2.getAge() + " " + person2.getFirstName() + " " + 
        person2.getLastName()+ " " + person2.getGender());
    
     }
    
    }
    

    Output

    Values in object person1 - 23 Ram Mishra M
    Values in object person2 - 21 Amita Chopra F
    

    Here you can see how using the constructor of the class, variables are initialized for both the objects and output shows that each instance of the class has its own values for the fields.

  2. Class Variables (Static Fields)- A class variable in Java is any field declared with the static modifier. As the name suggests class variable is at the class level and there will be exactly one copy of this variable in existence. Doesn’t matter how many instances (objects) of the class you have the class variable will have the same value, moreover you don’t even need the object to refer to the class variable.

    Java class variables example

    One common use of static fields is to create a constant value that's at a class level and applicable to all created objects.

    public class Employee {
     int empId;
     String name;
     String dept;
     // static constant
     static final String COMPANY_NAME = "XYZ";
     Employee(int empId, String name, String dept){
      this.empId = empId;
      this.name = name;
      this.dept = dept;
     }
     
     public void displayData(){
      System.out.println("EmpId = " + empId + " name= " + name + " dept = " + 
      dept + " company = " + COMPANY_NAME);
     }
     public static void main(String args[]){  
      Employee emp1 = new Employee(1, "Ram", "IT");
      Employee emp2 = new Employee(2, "Krishna", "IT");
      emp1.displayData();
      emp2.displayData();
     }
    }
    

    Output

    EmpId = 1 name= Ram dept = IT company = XYZ
    EmpId = 2 name= Krishna dept = IT company = XYZ
    
  3. Local Variables– Similar to how object store its state in fields, a method will store its temporary state in local variables in Java. Scope of local variable is in between the start and closing curly braces of a method. There is also a nested scope, suppose with in a method you have a if condition with its own starting and closing curly braces, then that block of code with in the if condition creates a nested scope. One more thing to note is you can have a local variable with the same name as class level variable with in the method and with in the method the local variable will take priority.

    Java local variables example

    public class InstanceDemo {
     // class level variable
     int x = 8;
     public static void main(String[] args) {
      
      InstanceDemo id = new InstanceDemo();
      
      id.display();
      System.out.println("value of class level variable x " + id.x);
     }
     
     public void display(){
      int x = 5;
      boolean flag = true;
      System.out.println("value of local variable x " + x);
      if (flag){
       int y = 10;
       System.out.println("value of local variable y inside if " + y);
      }
      // This will cause compile-time error
      //System.out.println("value of local variable y inside if " + y); 
     }
     
    }
    

    Output

    value of local variable x 5
    value of local variable y inside if 10
    value of class level variable x 8
    

    Here you see there is a class level variable and again it the method display() there is a variable with the same name x. When in the method value of local variable x takes priority and that is printed. Once out of method x that is recognized is the class level variable x.

    Another thing to note is the nested scope created by the if condition with in the display() method. Scope of variable y is in between the starting and closing braces of the if condition. Once you are out of if condition y won’t be recognized. Any attempt to print value of y outside the if condition scope will result in compile-time error.

  4. Parameters- Variables passed to any method are known as parameters. Any changes made to the primitive types parameter won’t change the original value.

    Java parameters example

    public class InstanceDemo {
     public static void main(String[] args) {
      
      InstanceDemo id = new InstanceDemo();
      int x = 10;
      id.display(x);
      System.out.println("value of x after method call " + x);
     }
     
     public void display(int x){
      
      x++;
      System.out.println("value of local variable x " + x);
     }
     
    }
    

    Output

    value of local variable x 11
    value of x after method call 10
    

    Here you have a variable x that is passed to display method as an int parameter. With in the method display() value of x is changed. But that change is local only and doesn’t change the original value of x. This is because copy of a variable is passed as a method parameter.

    If an object is passed as a parameter and any of that object’s field is changed, that change will be visible in other scopes too.

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

>>>Return to Java Basics Tutorial Page


Related Topics

  1. Java is a Strongly Typed Language
  2. Primitive Data Types in Java
  3. Access Modifiers in Java - Public, Private, Protected and Default
  4. What Are JVM, JRE And JDK in Java
  5. Object Creation Using new Operator in Java

You may also like-

  1. String in Java Tutorial
  2. Array in Java
  3. Count Number of Words in a String Java Program
  4. Ternary Operator in Java With Examples
  5. Java Multithreading Interview Questions And Answers
  6. Java Exception Handling Tutorial
  7. ConcurrentHashMap in Java With Examples
  8. TreeMap in Java With Examples

Friday, March 25, 2022

Covariant Return Type in Java

Before Java 5, when you overrode a superclass method in a subclass the method signature had to be exactly same, i.e. the name, argument types and return type of the overriding method in the sub-class had to be exactly same as that of the super-class method.

This is relaxed a bit in Java 5 in case of return type. The sub-class overridden method's return type may be different from super-class method's return type but the return type of the subclass' method should be a subtype of return type of super class method. Which means, if method in the super-class has return type R1 and the overriding method in the subclass has return type R2 then R2 must be a subtype of R1. That is known as covariant return type in Java.

Covariant name comes from the fact that the type of the return is allowed to vary in the same direction as the subclass.

Covariant return type in Java example

// used as return type
class A{
 String name;
 A(String name){
  this.name = name;
 }
}

//sub-class of A, also used as return type
class B extends A{
 B(String name){
  super(name);
 }
}

class C{
 public A getValue(){
  return new A("Test A");
 }
}

class D extends C{
 // overriding method, returning subtype of the 
 // super class method
 public B getValue(){
  return new B("Test B");
 }
}

public class CovariantDemo {

 public static void main(String[] args) {
  // Reference of Class C
  C c;
  // pointing to class C
  c = new C();
  System.out.println("Value from class C " + c.getValue().name);
  // now pointing to class D
  c = new D();
  System.out.println("Value from class D " + c.getValue().name);
 }
}

Output

Value from class C Test A
Value from class D Test B

It can be seen from the program that in class D which is the sub class of class C, getValue() method is overridden. In class C's getValue() method return type is A where as in the overridden method in class D return type is B, which is sub type of A, making it a covariant return type.

That's all for this topic Covariant Return Type 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. Varargs (Variable-length Arguments) in Java
  2. Enum Type in Java
  3. Method Overriding in Java
  4. Inheritance in Java
  5. Core Java Basics Interview Questions And Answers

You may also like-

  1. strictfp in Java
  2. static Import in Java With Examples
  3. Type Erasure in Java Generics
  4. Constructor Chaining in Java
  5. Interface Default Methods in Java
  6. Fail-Fast Vs Fail-Safe Iterator in Java
  7. Difference Between Comparable and Comparator in Java
  8. Deadlock in Java Multi-Threading

Thursday, March 24, 2022

Wiring Collections in Spring

In the post dependency injection in spring you would have seen examples of configuring both property values and reference to other beans. But these attributes property and ref can only be used with single fields. If you want to wire collections then Spring provides four options List, Set, Map and Props.


Options to wire collections in Spring

  • <list>- Used to wire a list of values in Spring, works with properties of any type of java.util.Collection and also arrays. As in Java list attribute allows duplicates, order is maintained.
  • <set>- Same as list with couple of differences - doesn’t allow duplicates, insertion order not maintained.
  • <map>- Used to wire a collection of (key, value) pair in Spring. Both key and value can be of any type.
  • <props>- Used to wire a collection of (key, value) pair. Both key and value have to be Strings.

Wiring List and Set in Spring example

Order class

Java class which has both List and Set fields.

import java.util.List;
import java.util.Set;

public class Order {
    private String id;
    private List<String> itemList;
    private Set<String> itemSet;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public List<String> getItemList() {
        return itemList;
    }
    public void setItemList(List<String> itemList) {
        this.itemList = itemList;
    }
    public Set<String> getItemSet() {
        return itemSet;
    }
    public void setItemSet(Set<String> itemSet) {
        this.itemSet = itemSet;
    }   
}

XML Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    
  <bean id="orderBean" class="org.netjs.prog.Order">
    <property name="id" value = "1" />
    <property name="itemList">
      <list>
        <value>Laptop</value>
        <value>RAM</value>
        <value>Drive</value>
        <value>Drive</value>
      </list>
    </property>
    <property name="itemSet">
      <set>
        <value>Laptop</value>
        <value>RAM</value>
        <value>Drive</value>
        <value>Drive</value>
      </set>            
    </property>
  </bean>
</beans>

You can run it using the following Java program-

import java.util.List;
import java.util.Set;
import org.netjs.prog.Order;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
        ("appcontext.xml");
   
    Order orderBean = (Order) context.getBean("orderBean");
    List<String> itemList = orderBean.getItemList();
    for(String item : itemList){
      System.out.println("item from List - " + item);
    }
    
    Set<String> itemSet = orderBean.getItemSet();
    for(String item : itemSet){
      System.out.println("item from set - " + item);
    }
  }
}

Output

creating instance of class Admin
creating instance of class Admin
item from List - Laptop
item from List - RAM
item from List - Drive
item from List - Drive
item from set - Laptop
item from set - RAM
item from set - Drive

Here it can be noted that Set has not stored duplicate value.

As mentioned above, List and Set can wire any type of java.util.Collection and also arrays, you can check it by changing the List and Set in Order class respectively to-

private String[] itemList;
private Collection<String> itemSet

without changing anything in XML configuration and it will work just fine.

Bean reference with List and Set

You can reference another bean too while wiring a List or Set.
Let's say we have two classes Order and Item.

Order class

import java.util.List;
import java.util.Set;

public class Order {
    private String id;
    private List<Item> itemList;
    private Set<Item> itemSet;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public List<Item> getItemList() {
        return itemList;
    }
    public void setItemList(List<Item> itemList) {
        this.itemList = itemList;
    }
    public Set<Item> getItemSet() {
        return itemSet;
    }
    public void setItemSet(Set<Item> itemSet) {
        this.itemSet = itemSet;
    }    
}

Item Class

public class Item {
    private String name;
    private double price;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }  
}

XML Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">

  <bean id="itemBean" class="org.netjs.prog.Item" >
    <property name="name" value = "Laptop" />
    <property name="price" value = "300.45" />
  </bean>
  <bean id="orderBean" class="org.netjs.prog.Order">
    <property name="id" value = "1" />
    <property name="itemList">
      <list>
        <ref bean="itemBean" />
        <bean class="org.netjs.prog.Item">
          <property name="name" value = "RAM" />
          <property name="price" value = "34.78" />
        </bean>
      </list>
    </property>
    <property name="itemSet">
      <set>
        <ref bean="itemBean" />
        <bean class="org.netjs.prog.Item">
          <property name="name" value = "Drive" />
          <property name="price" value = "50.67" />
        </bean>
      </set>        
    </property>
  </bean>
</beans>

Note here in Configuration there are two ways to refer another bean, you can either give a reference using ref attribute or within a list attribute you can define a bean.

You can run this using the following Java program.

import org.netjs.prog.Item;
import org.netjs.prog.Order;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
      ("appcontext.xml");
   
    Order orderBean = (Order) context.getBean("orderBean");
    List<Item> itemList = orderBean.getItemList();
    for(Item item : itemList){
      System.out.println("item from List - " + item.getName() + 
        " " + item.getPrice());
    }
    
    Set<Item> itemSet = orderBean.getItemSet();
    for(Item item : itemSet){
      System.out.println("item from set - " + item.getName() + " " + item.getPrice());
    }
  }
}

Output

creating instance of class Admin
creating instance of class Admin
item from List - Laptop 300.45
item from List - RAM 34.78
item from set - Laptop 300.45
item from set - Drive 50.67

Wiring Map and properties in Spring framework

With Map, Key and Value can be String or any other type so there are four options altogether, two for key and two for value.

  • key - Specifies the key of the map entry as a String
  • key-ref - Specifies the key of the map entry as a reference to another bean.
  • value - Specifies the value of the map entry as a String
  • value-ref - Specifies the value of the map entry as a reference to another bean.

With properties both key and value have to be String.

Order class

 
import java.util.Map;
import java.util.Properties;

public class Order {
  private String id;
  private Map<String, Item> itemMap;
  private Properties itemProp;
  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id;
  }
  public Map<String, Item> getItemMap() {
    return itemMap;
  }
  public void setItemMap(Map<String, Item> itemMap) {
    this.itemMap = itemMap;
  }
  public Properties getItemProp() {
    return itemProp;
  }
  public void setItemProp(Properties itemProp) {
    this.itemProp = itemProp;
  }    
}

Item Class

 
public class Item {
 private String name;
 private double price;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public double getPrice() {
  return price;
 }
 public void setPrice(double price) {
  this.price = price;
 } 
}

XML Configuration

 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    
  <bean id="itemBean" class="org.netjs.prog.Item" >
    <property name="name" value = "Laptop" />
    <property name="price" value = "300.45" />
  </bean>
  <bean id="orderBean" class="org.netjs.prog.Order">
    <property name="id" value = "1" />
    <property name="itemMap">
      <map>
        <entry key="1" value-ref="itemBean" />
        <entry key="2">
          <bean class="org.netjs.prog.Item">
            <property name="name" value = "RAM" />
            <property name="price" value = "34.78" />
          </bean>
        </entry>
      </map>
    </property>
    <property name="itemProp">
      <props>
        <prop key="Laptop">500</prop>
        <prop key="RAM">56.89</prop>
      </props>      
    </property>
  </bean>
</beans>

Here note that with Map also reference can be provided using the ref attribute or as inner bean definition.

You can run it using the following Java program.

 
import java.util.Map;
import java.util.Properties;
import org.netjs.prog.Item;
import org.netjs.prog.Order;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
       ("appcontext.xml");
   
    Order orderBean = (Order) context.getBean("orderBean");
    Map<String, Item> itemMap = orderBean.getItemMap();
    for(Map.Entry<String, Item> item : itemMap.entrySet()){        
      System.out.println("item from Map - " + item.getKey() + " " + 
      item.getValue().getName() + " " +  item.getValue().getPrice());
    }
    Properties itemProp = orderBean.getItemProp();
    System.out.println("items from Properties " + itemProp);
  }
} 

Output

creating instance of class Admin
creating instance of class Admin
item from Map - 1 Laptop 300.45
item from Map - 2 RAM 34.78
items from Properties {Laptop=500, RAM=56.89}

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

>>>Return to Spring Tutorial Page


Related Topics

  1. Dependency Injection Using factory-method in Spring
  2. Autowiring Using XML Configuration in Spring
  3. Autowiring Using Annotations in Spring
  4. Data Access in Spring Framework
  5. Using depends-on Attribute in Spring

You may also like-

  1. Spring Component Scan to Automatically Discover Beans
  2. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  3. Bean Definition Inheritance in Spring
  4. Spring MessageSource Internationalization (i18n) Support
  5. Executor And ExecutorService in Java With Examples
  6. Synchronization in Java - Synchronized Method And Block
  7. Producer-Consumer Java Program Using wait notify
  8. Java Program to Find The Longest Palindrome in a Given String

Wednesday, March 23, 2022

Java Program to Detect And Remove Loop in a Linked List

In this post we’ll see how to detect a loop or cycle in a linked list using a Java program and how to remove that loop in a linked list.

Linked list loop detection

If there is a loop in a linked list that means one of the node references back to any of the previous nodes rather than referencing the next node or null. Traversing a linked list with loop will cycle back to the old node rather than concluding its traversal once null is reached causing an infinite loop.

Following image shows how a linked list with a loop looks like.

detecting loop in linked list

Linked list loop detection Java program

There are various options for writing a Java program for linked list loop detection.

One of the approach is to use HashSet where you add each traversed node of the linked list to the HashSet, if the same node is encountered again trying to add will return false indicating a loop. But this approach requires extra space as another data structure HashSet is used.

The implementation which is widely used for linked list loop detection is Floyd's cycle-finding algorithm also known as "tortoise and the hare" algorithm. This implementation doesn’t require auxiliary space so space complexity is O(1) and time complexity is O(n) as linear traversal of the linked list is done.

Steps for implementing this algorithm are as follows-
  1. Use 2 references which are initialized to the head of the linked list.
  2. One of them hop a node and the other takes two hops in each iteration.
  3. If both of these references point to the same node at some iteration that means there is a loop.
  4. If any of these references reach null that means there is no loop in the linked list.
public class SinglyLinkedList {
 private Node head;
 SinglyLinkedList(){
  head = null;
 }
 static class Node{
  //data
  int i;
  Node next;
  Node(int i){
   this.i = i;
   this.next = null;
  }
 }
 // Method to add nodes to linked list
 public void insertLast(Node newNode){
  if(isEmpty()){
   head = newNode;
  }else{
   Node current = head;
   // traverse to the last of the list
   while(current.next != null){
    current = current.next;
   }
   // adding new node, current last node
   // starts referencing to this new node
   current.next = newNode;
  }
 }
 public boolean isEmpty(){
  return head == null;
 }
 public boolean isLoopDetected(){
  Node fast, slow;
  // start from head 
  fast = slow = head;
  while(slow != null && fast != null && fast.next != null){
   // hops two references
   fast = fast.next.next;
   // hops one reference
   slow = slow.next;
   if(fast == slow){
    return true;
   }
  }
  return false;
 }
 
 public static void main(String[] args) {
  SinglyLinkedList list = new SinglyLinkedList();
  Node node = new Node(30);
  list.insertLast(new Node(10));
  list.insertLast(new Node(20));
  list.insertLast(node);
  list.insertLast(new Node(40));
  list.insertLast(new Node(50));
  // same node inserted again to create loop
  list.insertLast(node);
  System.out.println("Loop detected? " + list.isLoopDetected());
 }
}

Output

Loop detected? True

Removing loop in linked list

In order to remove a loop in linked list three steps are required.

  1. First is of course to check whether a loop exists in a linked list or not.
  2. If a loop exists then both pointers will meet at some node. From there you will have to find the start node of the loop. For doing that set one of the pointers to the head and the other one remains at the point where both pointers met. From there move both of them sequentially (one reference at a time). The node where both these reference meet again would be the start of the loop.
  3. Once both slow and fast pointers are at the beginning of the loop if you move fast by one reference at a time ultimately it will again become equal to slow as it will cycle back because of the loop. That location of the fast where it becomes equal to the slow again is the end node of the loop.
    To remove loop in the liked list just set the next to null for the node referenced by fast.
public class SinglyLinkedList {
 private Node head;
 SinglyLinkedList(){
  head = null;
 }
 static class Node{
  //data
  int i;
  Node next;
  Node(int i){
   this.i = i;
   this.next = null;
  }
  public void displayData(){
   System.out.println("i= " + i);
  }
 }
 // Method to add nodes to linked list
 public void insertLast(Node newNode){
  if(isEmpty()){
   head = newNode;
  }else{
   Node current = head;
   // traverse to the last of the list
   while(current.next != null){
    current = current.next;
   }
   // adding new node, current last node
   // starts referencing to this new node
   current.next = newNode;
  }
 }
 public boolean isEmpty(){
  return head == null;
 }
 
 public Node findStartOfLoop(){
  Node fast, slow;
  fast = slow = head;
  boolean loopFlag = false;
  // to check for loop
  while(slow != null && fast != null && fast.next != null){
   fast = fast.next.next;
   slow = slow.next;
   if(fast == slow){
    loopFlag = true;
    break;
   }
  }
  // Find start of the loop
  if(loopFlag){
   System.out.println("Loop detected in liked list, finding start of the loop..");
   slow = head;
   while(slow != fast){
    slow = slow.next;
    fast = fast.next;
   }
  }else{
   System.out.println("No Loop detected in the linkedlist");
   fast = null;
  }
  return fast;
 }
 
 public void removeLoop(Node startNode){
  Node fast, slow;
  fast = slow = startNode;
  
  while(fast.next != slow){
   fast = fast.next;
  }
  fast.next = null;
 }

 // Method to traverse and display all nodes
 public void displayList(){
  Node current = head;
  while(current != null){
   current.displayData();
   current = current.next;
  }
 }
 public static void main(String[] args) {
  SinglyLinkedList list = new SinglyLinkedList();
  Node node = new Node(30);
  list.insertLast(new Node(10));
  list.insertLast(new Node(20));
  list.insertLast(node);
  list.insertLast(new Node(40));
  list.insertLast(new Node(50));
  // same node inserted again to create loop
  list.insertLast(node);
  
  Node loopStartNode = list.findStartOfLoop();
  System.out.println("Start node of the loop- " + loopStartNode.i);
  list.removeLoop(loopStartNode);
  list.displayList();
 }
}

Output

Loop detected in liked list, finding start of the loop..
Start node of the loop- 30
i= 10
i= 20
i= 30
i= 40
i= 50

In the code initially start node of the loop is searched and using that end node is searched. Once the end node of the loop is found its next reference is changed to null. Now the list can be traversed with going into an infinite loop.

That's all for this topic Java Program to Detect And Remove Loop in a Linked List. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Queue Implementation in Java Using Linked List
  2. How to Reverse a Doubly Linked List in Java
  3. Linear Search (Sequential Search) Java Program
  4. Heap Sort Program in Java
  5. How to Display Pyramid Patterns in Java - Part1

You may also like-

  1. Creating Tar File And GZipping Multiple Files in Java
  2. How to Read Properties File in Java
  3. Difference Between Two Dates in Java
  4. Find Largest and Second Largest Number in Given Array Java Program
  5. How HashMap Internally Works in Java
  6. Generics in Java
  7. Conditional Operators in Java
  8. Spring Web MVC Tutorial

Monday, March 21, 2022

Java String Search Using indexOf(), lastIndexOf() And contains() Methods

There are scenarios when you want to find characters or substrings within a String. For that purpose String class in Java provides accessor methods that return the position within the string of a specific character or substring: indexOf() and lastIndexOf().

  • indexOf()- This method searches forward from the beginning of the string and returns the index within this string of the first occurrence of the specified character/substring. If a character or substring is not found indexOf() returns -1.
  • lastIndexOf()- This method searches backward from the end of the string and returns the index within this string of the last occurrence of the specified character/substring. If a character or substring is not found lastIndexOf() returns -1.

The String class also provides a search method, contains, that returns true if the string contains a particular character sequence. Use this method when you only need to know that the string contains a character sequence, but the precise location isn't important.

indexOf() and lastIndexOf() methods in String

There are various overloaded versions of indexOf() and lastIndexOf() methods.

Java indexOf() method

  • indexOf(int ch)- Returns the index within this string of the first occurrence of the specified character.
  • indexOf(int ch, int fromIndex)- Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.
  • indexOf(String str)- Returns the index within this string of the first occurrence of the specified substring.
  • indexOf(String str, int fromIndex)- Returns the index within this string of the first occurrence of the specified substring, starting at the specified index.

Java lastIndexOf() method

  • lastIndexOf(int ch)- Returns the index within this string of the last occurrence of the specified character.
  • lastIndexOf(int ch, int fromIndex)- Returns the index within this string of the last occurrence of the specified character, searching backward starting at the specified index.
  • lastIndexOf(String str)- Returns the index within this string of the last occurrence of the specified substring.
  • lastIndexOf(String str, int fromIndex)- Returns the index within this string of the last occurrence of the specified substring, searching backward starting at the specified index.

Searching for character in a String using indexOf() and lastIndexOf() methods

  1. If you get date as String in the dd/mm/yyyy format and you want to get the first index of char '/'.
    public class StringSearch {
     public static void main(String[] args) {
      String date = "12/01/2016";
      System.out.println("index " + date.indexOf('/'));
     }
    }
    

    Output

    index 2
    
  2. Using the same date string if you want to get the month part of it.
    public class StringSearch {
     public static void main(String[] args) {
      String date = "12/01/2016";
      System.out.println("index " + date.indexOf('/'));
      String month = date.substring(0, date.indexOf('/'));
      System.out.println("month " + month);
     }
    }
    

    Output

    index 2
    month 12
    
  3. Using the same date string if you want to get the year part then you can use lastIndexOf() method.
    public class StringSearch {
     public static void main(String[] args) {
      String date = "12/01/2016";
      System.out.println("index " + date.lastIndexOf('/'));
      String year = date.substring(date.lastIndexOf('/') + 1);
      System.out.println("year " + year);
     }
    }
    

    Output

    index 5
    year 2016
    
  4. If you get some string in the format “xx/xx/xx” and you want the middle substring.
    public class StringSearch {
     public static void main(String[] args) {
      String path = "home/index/test.html";
      
      String str = path.substring(path.indexOf('/') + 1, path.lastIndexOf('/'));
      System.out.println("str - " + str);
     }
    }
    

    Output

    str - index
    

Searching for substring in a String using indexOf() and lastIndexOf() methods

Same way you can also use indexOf() and lastIndexOf() methods to search for a substring within a given string.

public class StringSearch {
  public static void main(String[] args) {
    String str = "This is a test String to test searching in String";
    System.out.println("First occurrence of String test is at index- "
             + str.indexOf("test"));
    System.out.println("Last occurrence of String test is at index- " 
             + str.lastIndexOf("test"));
    System.out.println("Content between fist and last occurrence of test in the String- " 
             + str.substring(str.indexOf("test"), str.lastIndexOf("test")));
     
    System.out.println("First occurrence of String test after index 15- " 
             + str.indexOf("test", 15));
  }
}

Output

First occurrence of String test is at index- 10
Last occurrence of String test is at index- 25
Content between fist and last occurrence of test in the String- test String to 
First occurrence of String test after index 15- 25

Searching in String using contains() method

public boolean contains(CharSequence s)- Returns true if and only if this string contains the specified sequence of char values. Otherwise it returns false.

Java contains() method example

public class StringSearch {

 public static void main(String[] args) {
  String str1 = "Contains example";
  String str2 = "example";
  System.out.println("str1 contains str2 " + str1.contains(str2));
 }
}

Output

str1 contains str2 true

Here note that str2 which is passed as an argument in contains() method is a string not CharSequence, so string can be used in place of CharSequence. It is possible because CharSequence is an interface which is implemented by String.

If you want to use contains() method ignoring case then you can convert both strings to upper or lowercase while searching.

For example in previous program if str2 is changed to “Example” then contains will return false.

public class StringSearch {
 public static void main(String[] args) {
  String str1 = "Contains example";
  String str2 = "Example";
  System.out.println("str1 contains str2 " + str1.contains(str2));
 }
}

Output

str1 contains str2 false

Now, if you want to ignore case then you can change both to lower case.

public class StringSearch {
 public static void main(String[] args) {
  String str1 = "Contains example";
  String str2 = "Example";
  System.out.println("str1 contains str2 " + str1.toLowerCase().contains(
   str2.toLowerCase()));
 }
}
str1 contains str2 true

It won't change the original strings as strings are immutable and using methods like toLowerCase will create a new string.

That's all for this topic Java String Search Using indexOf(), lastIndexOf() And contains() Methods. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related topics

  1. String Comparison in Java equals(), compareTo(), startsWith() Methods
  2. Java String substring() Method - Getting Substring
  3. Is String Thread Safe in Java
  4. Splitting a String Using split() Method in Java
  5. Java String Interview Questions And Answers

You may also like-

  1. Find All Permutations of a Given String Java Program
  2. equals() And hashCode() Methods in Java
  3. Fail-Fast Vs Fail-Safe Iterator in Java
  4. Method Reference in Java
  5. Abstraction in Java
  6. Difference Between equals() Method And equality Operator == in Java
  7. static Block in Java
  8. Difference Between component-scan And annotation-config in Spring

Sunday, March 20, 2022

Best Practices For Exception Handling in Java

If you know about these 5 keywords try, catch, finally, throw and throws and how to use them, you pretty much know what Java exception handling is all about.

But there are also some best practices for exception handling in Java which you should try to follow. That is what this post talks about; the do’s and don'ts of the exception handling in Java.

Java Exception Handling Best Practices

  1. Use Specific Exceptions not Exception or Throwable- It is always better to throw specific exception (specific exception sub-classes) rather than the more generic one (i.e. super class) like Throwable, Exception or RunTimeException.

    By doing that we can provide more information to the user what exactly went wrong, the code is also more readable by giving info about various exceptions it can throw rather than everything gobbled up by Exception or Throwable class.

    We should be specific when catching exceptions too. As Example- For RunTimeExceptions (unchecked exceptions) it is said that we should not catch them as they indicate application code errors. If we catch Exception class directly we also catch RuntimeExceptions as RuntimeException class inherits from Exception.

    Same way if we catch throwable directly that is also wrong-

    try {
    } catch(Throwable t) {
        t.printStackTrace();//Should not do this
    }
    

    Throwable is the superclass of all errors and exceptions in Java. Error is the superclass of all errors which are not meant to be caught by applications. Thus, catching Throwable would essentially mean that Errors such as system exceptions (e.g., OutOfMemoryError, StackOverFlowError) would also get caught. And, the recommended approach is that application should not try and recover from Errors such as these. Thus, Throwable and Error classes should not be caught. Only Exception and its subclasses should be caught.

  2. Throw Early or Fail-Fast- Since an exception stack trace shows the exact sequence of method calls till the point of exception, along with class name, file name and the line number where the exception occurs it becomes very important to throw exception as early as possible.

    Let's see what will happen if we don't do that.

    public class ShowFile {
      public static void main(String[] args) {
        File propFile = new File("");
        try{
          readFile(propFile);
        }catch (FileNotFoundException e){
          e.printStackTrace();
        }catch (EOFException e){
          e.printStackTrace();
        }catch (IOException e){
          e.printStackTrace();
        }
      }
        
      private static void readFile(File filename) throws 
          FileNotFoundException, EOFException{
        InputStream in = new FileInputStream(filename);       
      }
    }
     

    StackTrace

    java.io.FileNotFoundException: 
     at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at org.netjs.example.ShowFile.readFile(ShowFile.java:37)
        at org.netjs.example.ShowFile.main(ShowFile.java:18)
    

    In the stack trace it is a little difficult to point out the real origin of exception, seeing the stack trace it looks like problem is in FileInputStream though in reality, problem in the code is that there is no check for space passed as file name.

    Let's see how we should do that.

    public class ShowFile {
      public static void main(String[] args) {
        File propFile = new File("");
        try{
          readFile(propFile);
        } catch (FileNotFoundException e){
          e.printStackTrace();
        } catch (IOException e){
          e.printStackTrace();
        }
      }
        
      private static void readFile(File fileName) throws FileNotFoundException, 
          EOFException, IllegalArgumentException{
        if(fileName == null || fileName.getPath().equals("")){
          throw new IllegalArgumentException("File Name not given");
        }
        InputStream in = new FileInputStream(fileName);  
      }
    }
    

    StackTrace

    Exception in thread "main" java.lang.IllegalArgumentException: File Name not given
     at org.netjs.example.ShowFile.readFile(ShowFile.java:42)
     at org.netjs.example.ShowFile.main(ShowFile.java:18)
    

    It can be seen now with the check for the filename the stack trace gives precise information about the problem.

  3. Catch Late- In case of checked exceptions, it is enforced by Java compiler to either catch the exception or declare it in throws clause. So generally developer tends to catch it and do nothing, except printing stacktrace or put a logger, in order to avoid the compiler error. But that way we are not providing the true information of what exactly happened.

    Lets see an example-

    public class ShowFile {
      public static void main(String[] args) {
        File propFile = new File("");
        readFile(propFile);        
      }
        
      private static void readFile(File fileName) {
        InputStream in = null;
        try {
          in = new FileInputStream(fileName);
        } catch (FileNotFoundException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        try {
          in.read();
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }        
      }
    }
    

    Stacktrace

    java.io.FileNotFoundException: 
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at org.netjs.example.ShowFile.readFile(ShowFile.java:41)
        at org.netjs.example.ShowFile.main(ShowFile.java:18)
    Exception in thread "main" java.lang.NullPointerException
        at org.netjs.example.ShowFile.readFile(ShowFile.java:47)
        at org.netjs.example.ShowFile.main(ShowFile.java:18)
    

    Here you can see that instead of declaring the exception in throws clause and catching it at the point where it can be handled, try-catch block is used and the exception is caught using FileNotFoundException. If we see the stack trace it is not providing appropriate and precise information why the exception occurred.

    It is better to catch exception only when it can be handled appropriately. We can use throws clause to declare the exception and put the responsibility of catching them on the caller method. This way exception handling has been passed further up the call chain.

    public class ShowFile {
      public static void main(String[] args) {
        File propFile = new File("");
        try{
          readFile(propFile);
        } catch (FileNotFoundException e){
          e.printStackTrace();
        } catch (IOException e){
          e.printStackTrace();
        }    
      }
        
      private static void readFile(File fileName) throws FileNotFoundException, 
          IOException, IllegalArgumentException{
        if(fileName == null || fileName.getPath().equals("")){
          throw new IllegalArgumentException("File Name not given");
        }                 
        InputStream in = new FileInputStream(fileName);
        in.read();                
      }
    }
    
  4. Do not suppress exceptions- The whole idea of having a checked exception in Java is to give a chance to take some action to recover from the raised exception. So ignoring it by having empty braces in the catch block or just printing the stack trace or logging a checked exception and continue with the code is not a best practice.
    try {
      /* ... */
    } catch( Exception e ) {
    
    }
     
    try {
      /* ... */
    } catch( Exception e ) {
      // The exception thrown is lost
      Logger.info( "some exception occured" ); 
    }
    

    We should always avoid empty catch block that just consumes the exception and doesn't provide any meaningful details of exception for debugging purposes.

  5. Don't lose the original exception- Almost all the exception classes provide a constructor with the cause as parameter.
     public Exception(String message, Throwable cause)
    

    Always use the constructor with cause parameter to keep the original exception.
    As example- If some exception is thrown and you want to wrap it in a custom exception-

     
    catch (IllegalArgumentException exp) {
       throw new MyCustomException("Exception caught: " + e.getMessage());  //Incorrect way
    }
    

    This destroys the stack trace of the original exception, and is always wrong. The correct way of doing this is:

     
    catch (IllegalArgumentException exp) {
       throw new MyCustomException ("Exception caught: " , exp);  //Correct way
    }
    
  6. Custom Exception as checked Exception or Unchecked Exception- If user can take some action to recover from the expected error then make the custom exception a checked exception. On the other hand if user cannot do anything useful in case of error then make the custom exception as an unchecked exception (i.e. inheriting from RunTimeException).

    Most of the time only function of the custom exceptions is to log an error; in that case it should definitely be an unchecked exception.

  7. Follow Naming Convention for exceptions- When creating your own custom exception follow the already established naming convention for exception classes like always end the class name with Exception like NoSuchMethodExcpetion, MyAppException etc.

    Also try to keep the same type of exceptions in the same hierarchy like IOExcpetion is the base class exception for all the IO related exceptions.

  8. Java exception performance consideration- Exceptions do have an impact on the overall performance of the application so use them judiciously. Don't just throw and catch exceptions, if you can use boolean variable to indicate whether an operation was successful or not they try to return a Boolean variable to a caller program and decide the flow of the code based on the returned Boolean.

    Avoid unnecessary Exception handling by fixing root cause. Also check for null yourself before performing any operation or check the array length yourself rather than relying on ArrayIndexOutOfBoundException.

  9. Document the Exceptions Thrown- Use javadoc @throws to clearly specify the exceptions thrown by the method, it's very helpful when you are providing an interface to other applications to use.
  10. Exceptions should not be used for flow control- Raising and handling exception is an expensive operation and should be used for exceptional conditions only. Using it for flow control hits the overall performance and is a strict no no.
    Always check for array length and null values rather than relying on exception handling to do that.

    As example, always check for the array length in a loop

     
    for (int i=0; i < tempArray.length; i++) {
      // code using the tempArray
    }
    
    Don't rely on try-catch block
     
    try {
      for (int i=0; ; i++) {
        // code using the tempArray
      }
    } catch (ArrayIndexOutOfBoundsException ex) {
       …..
    }
    

    Check for null with in a code-

     
    if(obj != null){
    	obj.getValue();
    }
    
    Or
    if(someMap.contains(obj)){
        someMap.get(obj);
    } 
    
    Is a better solution than having a try-catch block to do catch a null pointer exception.
    try{
        Obj.getValue()   
    }catch(RuntimeException exp){
       ....
    }
    
  11. Clean up the resources- If you are using resources like database connections, network connections or IO streams, make sure you clean them up using finally block or using the Java 7 ARM feature.

  12. Logging Exceptions and providing helpful message - We should always log exception messages and while throwing exception provide clear message so that caller will know easily why the exception occurred. Always append values in the exception message if possible.

    As example- If we are writing some code where some specific logic is there for senior citizens (Age greater than or equal to 60) and the method throws InvalidAgeException if age is less than 60.

    In that case if exception is thrown then displaying a message "Exception thrown from method METHOD_NAME" or "Invalid parameter" will not be as helpful as saying "Invalid age exception for " + {age}

    That way whoever is seeing the log can easily figure out what was the parameter given when the exception was thrown.

  13. Log and throw anti-pattern- Logging and throwing the exception with in a catch block is considered an error handling anti-pattern and should be avoided.
    catch (NoSuchFieldException exp) {
       LOG.error("Exception occurred", exp);
       throw exp;
    }
    
    Consider the above example code, doing both logging and throwing will result in multiple log messages in log files, for a single problem in the code. Whoever is going through the log will have to go through multiple logs for the same error rather than at one place in a log.

  14. Preserve loose coupling- One of the best practices for the exception handling is to preserve loose coupling. According to that an implementation specific checked exception should not propagate to another layer. As Example SQL exception from the DataAccessCode (DAO layer) should not propagate to the service (Business) layer. The general practice in that case is to convert database specific SQLException into an unchecked exception and throw it.
    catch(SQLException ex){
        throw new RuntimeException("DB error", ex);
    }
    

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


Related Topics

  1. Creating Custom Exception Class in Java
  2. final Vs finally Vs finalize in Java
  3. Multi-Catch Statement in Java Exception Handling
  4. Try-With-Resources in Java Exception Handling
  5. Java Exception Handling Interview Questions And Answers

You may also like-

  1. Fail-Fast Vs Fail-Safe Iterator in Java
  2. How HashMap Internally Works in Java
  3. Thread States (Thread Life Cycle) in Java Multi-Threading
  4. Lambda Expression Examples in Java 8
  5. Interface Default Methods in Java
  6. ConcurrentHashMap in Java With Examples
  7. Java ArrayBlockingQueue With Examples
  8. Effectively Final in Java 8