Java Short-Circuit Evaluation | Java Operators

There are so many operators available in Java. Here we will discuss Java Short circuit operators and how they evaluate the given expression. As a Java developer, you must know these basics and how to use them effectively.

OperatorEvaluation
&& and ||Short-Circuit
& and |Full

Operator && and || are known as short-circuit operators and how they evaluate an expression is known as short circuit evaluation.

What exactly Short-circuit evaluation is?

The short circuit evaluation enables you to not evaluate the right-hand side AND or OR expression when the overall result of the expression can be predicted from the left-hand side value.

So for AND (&&), both parts must be true for the overall results to be true. For OR (||), one part must be true, either one of these. The other may be false, it doesn’t matter. The overall result will be true. And for exclusive OR (^), either part has to be true, and the other part has to be false for the overall result to become true.

Now, instead of the double ampersand (&&) and double vertical line (||), there are also single ampersand and single vertical line operators available, and they’re known as full evaluation versus the double ampersand and double vertical line, which are known as short circuit evaluation.

Refer to the below picture and see how the evaluation of these operators happens.

Java Short-Circuit Evaluation

Example

Now let’s understand this using the below code snippet.

 
int a = 3, b = 2;
boolean c = false;

c = (a > b && ++b == 3); 
System.out.println("value of c is "+c + " and b is "+b);

c = (a > b && ++b == 3);
System.out.println("value of c is "+c + " and b is "+b);

c = (a > b || ++b == 3); 
System.out.println("value of c is "+c + " and b is "+b);

c = (a < b || ++b == 3); 
System.out.println("value of c is "+c + " and b is "+b);

c = (a < b | ++b == 3); 
System.out.println("value of c is "+c + " and b is "+b);

c = (a > b & ++b == 3);
System.out.println("value of c is "+c + " and b is "+b);

c = (a < b ^ ++b == 3);
System.out.println("value of c is "+c + " and b is "+b);

c = (a > b ^ ++b == 3);
System.out.println("value of c is "+c + " and b is "+b);

//Output
value of c is true and b is 3
value of c is false and b is 3
value of c is false and b is 4
value of c is true and b is 4
value of c is true and b is 5
value of c is false and b is 6
value of c is true and b is 7
value of c is false and b is 8

Note: You don’t have to put round brackets around Booleans, but that may make your code a little bit more readable, just sort of from a visual point of view so the Boolean expression will stand out.

Output Explantion

Let’s understand the output of each line.

 c = (a > b && ++b == 3); 

For AND condition, both parts of the expression need to be true for the overall results to become true. So we have to evaluate both parts to tell that.

If you look at a Boolean expression, the double ampersand is AND, the first part evaluates to true and then ++b increment the b to 3 and it also evaluates to true. That’s why c is true and b is 3.

See the next line of code which is a copy of the first line but its output is different from the first line. In this case, the first condition evaluates to false as b is incremented to 3 in the first line. Hence the second part of the expression will not be evaluated.

 c = (a > b || ++b == 3);  

OR condition, here one part of the expression needs to be true for the overall results to become true. So we have to evaluate both parts to tell that.

If you look at a Boolean expression, the first part evaluates to false and then ++b increment the b to 4 and it also evaluates to false. That’s why c is false and b is 4.

The next line also used the OR operator but changed the first part of the condition to a < b.

 c = (a < b || ++b == 3);  

In this case the first part evaluates to true hence the second part of the expression is omitted from the evaluation. That’s why c is true and b is still 4.

The next line also used the OR operator but not the short circuit one. This time we used the full evaluation of OR (|) means a single vertical line. The difference in full evaluation is even if the first condition of the OR is true the second part will still be evaluated and it doesn’t impact the overall result of the expression.

 c = (a < b | ++b == 3);  

Hence, in the output of the above line value of c is true and b is incremented to 5.

The next line is having the full evaluation AND operator. These means don’t matter the first condition evaluates to true or false the second condition will be evaluated which is not the case when we use short circuit AND (&&) operator.

 c = (a > b & ++b == 3);  

In the above line the first condition is evaluated to false but still, the second condition is evaluated which is not the case when we use &&. Hence The value of c is false in the output of the above line but the b is still incremented to 6.

The next two lines of the code are using XOR (^) operator. This is also used for a full evaluation of both the expression. This will return true if one condition is true and another is false.

 c = (a < b ^ ++b == 3);  

Here the first condition is evaluated to true then it increments b to 7 and the second condition evaluates to false.

 c = (a > b ^ ++b == 3);  

The last line output value of c is false and b is 8. Here if you see the first condition is evaluated to false then it incremented b to 8 and that condition is false.

Conclusion

Here we discussed the &&, ||, &, | and ^ operators and how they evaluate a given condition. While using full evaluation the second part of the condition is evaluated doesn’t matter the first condition is evaluated to true or false.

Happy Learning !!

Read more

Refrence

Java Generic, Generic with super and wildcard

Generics allow you to specify concrete types to general-purpose classes and methods that operate on java.lang.Object before. It was added to Java from Java 5. The Java collection framework used generics a lot.

Let see some example of life without generics.

List list = new ArrayList(); 
list.add("String");
list.add("1");
list.add(1);

In the above example, we have created a list without specifying any data type. This means we can add data of any type to it and it requires external typecasting during retrieval. As soon as we try to access the element and assign it to a different data type, it will greet you with errors like the below:

Integer num =  list.get(2);

//Type mismatch: cannot convert from Object to Integer

There are two solutions to it.

1. Cast it to Integer
2. Change the type of num to Object.

To avoid such issues we use generic, let’s rewrite the above code with generics.

List<String> list = new ArrayList<>(); 
list.add("String");
list.add("1");
// list.add(1);

Now as soon as we defined the type of List as “String” if we try to add an Integer to it as per the commented line, the compiler will prompt the error as follow:

The method add(int, String) in the type List is not applicable for the arguments (int).

This is the benefit of using generic.

Generic Classes:

Similar to generic classes defined inside Java APIs, we can also define our generic classes.

Refer to the below Generic class Implementation with an example.

class InstanceFactory<T> {

    Class<T> theClass = null;
    
        public InstanceFactory(Class<T> theClass) {
            this.theClass = theClass;
        }
    
        public T getInstance() throws IllegalAccessException, InstantiationException {
            return this.theClass.newInstance();
        }
   }  
      
    public class GenericInDepth {

    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        
        InstanceFactory<Animal> factory = new InstanceFactory<>(Animal.class);

        Animal instance = factory.getInstance();
        
        instance.showType();
        
    }
}

Generic Methods:

We can also define generic methods in Java-like we did generic classes. Let see the below code snippet.

public class GenericInDepth {

    public static void main(String[] args) {
        
        List<String> list = new ArrayList<>();
        list.add("hello");
        System.out.println("string list 1 "+ list);
    
        addElement("world", list);
        
        System.out.println("string list 2 "+ list);
        
        
        List<Integer> nums = new ArrayList<>();
        
        addElement(12, nums);
        
        System.out.println("int list 1 "+ nums);
        
    }
   
    public static <T> void addElement(T t, Collection<T> col) {
         col.add(t);
    }   
}

Output:

string list 1 [hello]
string list 2 [hello, world]
int list 1 [12]

Generic and wildcard:

The Java generic allows us to cast the collection of a certain class to a collection of subclass or superclass. Let see the problem without a wildcard first.

Let’s create Three classes Pet, Cat, and Dog as below. Where Pet is the parent class of both Cat and Dog.

class Pet {

    private int petId;
    private String type;
    
    public Pet(int petId, String type) {
        this.petId = petId;
        this.type= type;
    }

    @Override
    public String toString() {
        return "Pet [petId=" + petId + ", type=" + type + "]";
    }

    public String getType() {
        return this.type;
    }
}

class Cat extends Pet{

    public Cat(int petId) {
        super(petId, "Cat");
    }
    
}

class Dog extends Pet{

    public Dog(int petId) {
        super(petId, "Dog");
    }
    
}

Now let’s create three List using the Pet, Cat, and Dog classes as following.

public class GenericInDepth {

    public static void main(String[] args) {
        
        List<Pet> pList = new ArrayList<>(); 
        pList.add(new Pet(1, "Cat"));
        
        pList.add(new Cat(4));
        
        
        System.out.println(pList);
        
        List<Cat> cList = new ArrayList<>();
        
        cList.add(new Cat(2));
        
        System.out.println(cList);
        
        List<Dog> dList = new ArrayList<>();
        dList.add(new Dog(3));
    
        System.out.println(dList);
	}
}

We can only add an object of Pet and objects of its subclasses Cat and Dog in pList. But if we do the following it will prompt compile-time error, Type mismatch: cannot convert from List to List

pList = cList;

The reason for the compile-time error is:

If you could make this assignment, it would be possible to insert Pet and Dog instances into the List pointed to by CList. You could do that via the pList reference, which is declared to be of List. Thus you could insert non Cat objects into a list declared to hold Cat (or Cat subclass) instances.

Now suppose we have defined a method to print the type of pet from a collection of pets.

public static void printType(List<Pet> pets) {
  System.out.println("printing type");
  for(Pet p : pets) {
        System.out.println(p.getType());
  }
}

The method printType() will not work if we pass it to the list of Cat or list of Dog.

The need for a wildcard in generic arise to solve the above-mentioned problem.

Type of wildcard generics:

1. The ? extends wildcard.
2. The ? super wildcard.

To understand the use of extends read inheritance in java

Use the ? extends wildcard if you need to retrieve an object from a collection, it is read-only. You can’t add elements to the collection. Which means retrieval of the instance from the collection of Pet or its subclasses.

Use the ? super wildcard if you need to add objects in a collection, it will allow adding an object of Pet or its subclasses.

Java Generic and wildcard

Let’s modify the printType() method to accept the child of Pet (both Cat and Dog) as well to retrieve the object.

public static void printType(List<? extends Pet> pets) {
      // pets.add(new Cat(5)); 
	System.out.println("printing type");
    for(Pet p : pets) {
    	System.out.println(p.getType());
	}
}

But if we try to add an object of Cat to “pets” inside the above method as the commented line. It will prompt compile-time error as extends only allow retrieval.

To add items into this collection we can create a method addPet() like below.

public static void addPet(Pet p, List<? super Pet> pets) {
     pets.add(p);
}

Now if we call addPet(new Cat(6),pList); it will work perfectly.

Reference:

https://docs.oracle.com/javase/tutorial/java/generics/index.html

Happy Learning !!

Favor composition over inheritance Effective Java

According to Effective Java Item 16: Favor composition over inheritance.

Inheritance is a powerful way to achieve code reuse, but it is not always the best tool for the job. Used inappropriately, it leads to fragile software. It is safe to use inheritance within a package, where the subclass and the superclass implementations are under the control of the same programmers. It is also safe to use inheritance when extending classes specifically designed and documented for the extension. Inheriting from ordinary concrete classes across package boundaries, however, is dangerous.

composition over inheritance

Unlike method invocation, inheritance violates encapsulation. In other words, a subclass depends on the implementation details of its superclass for its proper function. The super class’s implementation may change from release to release, and if it does, the subclass may break, even though its code has not been touched. As a consequence, a subclass must evolve in tandem with its superclass, unless the super class’s authors have designed and documented it specifically for the purpose of being extended.

Consider this broken class, which is trying to keep track of how many items has been added to the InstrumentedHashSet:

import java.util.Collection;
import java.util.HashSet;

public class InstrumentedHashSet<E> extends HashSet<E> {

	private static final long serialVersionUID = -7204141288621349906L;

	// The number of attempted element insertions
	private int addCount = 0;

	public InstrumentedHashSet() {
	}

	public InstrumentedHashSet(int initCap, float loadFactor) {
		super(initCap, loadFactor);
	}

	@Override
	public boolean add(E e) {
		addCount++;
		return super.add(e);
	}

	@Override
	public boolean addAll(Collection<? extends E> c) {
		addCount += c.size();
		return super.addAll(c);
	}

	public int getAddCount() {
		return addCount;
	}
}

When we use the add () method to add an element to an instance of this class it works fine and returns the add count as expected. Observe the below code snippet.

public class CompositionOverInheritance {

	public static void main(String[] args) {
		InstrumentedHashSet<String> s = new InstrumentedHashSet<>();
		
		s.add("Snap");
		s.add("Crackle");
		s.add("Pop");
		
		System.out.println("add count "+s.getAddCount()); // the output will be 3 as expected.
		
	}
}

However when we create an instance of this class and add elements using addAll () method as we have done in the below code snippet the output is not as expected.

import java.util.Arrays;

public class CompositionOverInheritance {

	public static void main(String[] args) {
		InstrumentedHashSet<String> s = new InstrumentedHashSet<>();

		s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
		
		System.out.println("add count "+s.getAddCount()); 
		
	}
}

We would expect the getAddCount method to return three at this point, but it returns six. What went wrong? Internally, HashSet’s addAll method is implemented on top of its add method, although HashSet, quite reasonably, does not document this implementation detail. The addAll method in Instrumented- HashSet added three to addCount and then invoked HashSet’s addAll implementation using super.addAll. This, in turn, invoked the add method, as overridden in InstrumentedHashSet, once for each element. Each of these three invocations added one more to addCount, for a total increase of six: each element added with the addAll method is double-counted.

The solution to the problems described above is, instead of extending an existing class, give your new class a private field that references an instance of the existing class. This design is called composition because the existing class becomes a component of the new one. Each instance method in the new class invokes the corresponding method on the contained instance of the existing class and returns the results. This is known as forwarding, and the methods in the new class are known as forwarding methods. The resulting class will be rock solid, with no dependencies on the implementation details of the existing class. Even adding new methods to the existing class will have no impact on the new class.

here’s a replacement for InstrumentedHashSet that uses the composition-and-forwarding approach. Note that the implementation is broken into two pieces, the class itself and a reusable forwarding class, which contains all of the forwarding methods and nothing else.

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

// Wrapper class - uses composition in place of inheritance
public class InstrumentedHashSet<E> extends ForwardingSet<E> {
	private int addCount = 0;

	public InstrumentedHashSet(Set<E> s) {
		super(s);
	}

	@Override
	public boolean add(E e) {
		addCount++;
		return super.add(e);
	}

	@Override
	public boolean addAll(Collection<? extends E> c) {
		addCount += c.size();
		return super.addAll(c);
	}

	public int getAddCount() {
		return addCount;
	}
}

// Reusable forwarding class
class ForwardingSet<E> implements Set<E> {
	private final Set<E> s;

	public ForwardingSet(Set<E> s) {
		this.s = s;
	}

	public void clear() {
		s.clear();
	}

	public boolean contains(Object o) {
		return s.contains(o);
	}

	public boolean isEmpty() {
		return s.isEmpty();
	}

	public int size() {
		return s.size();
	}

	public Iterator<E> iterator() {
		return s.iterator();
	}

	public boolean add(E e) {
		return s.add(e);
	}

	public boolean remove(Object o) {
		return s.remove(o);
	}

	public boolean containsAll(Collection<?> c) {
		return s.containsAll(c);
	}

	public boolean addAll(Collection<? extends E> c) {
		return s.addAll(c);
	}

	public boolean removeAll(Collection<?> c) {
		return s.removeAll(c);
	}

	public boolean retainAll(Collection<?> c) {
		return s.retainAll(c);
	}

	public Object[] toArray() {
		return s.toArray();
	}

	public <T> T[] toArray(T[] a) {
		return s.toArray(a);
	}

	@Override
	public boolean equals(Object o) {
		return s.equals(o);
	}

	@Override
	public int hashCode() {
		return s.hashCode();
	}

	@Override
	public String toString() {
		return s.toString();
	}
}

Here when we create an instance of InstrumentedHashSet class and call addAll () method the addCount() method will return the correct item count as expected. Refer to the below code snippet and the output.

import java.util.Arrays;
import java.util.TreeSet;

public class CompositionOverInheritance {

	public static void main(String[] args) {
		InstrumentedHashSet<String> s = new InstrumentedHashSet<>(new TreeSet<String>());
		
		s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
		System.out.println("add count "+s.getAddCount());  //add count 3
		
	}
}

Read more about inheritance.

Happy Learning !!

Shallow Copy vs Deep Copy Java

Object cloning is a way to create a copy of an object. The clone method of java.lang.Object class is used to clone the object. In this tutorial, we will discuss the Shallow Copy vs Deep Copy.

Shallow Copy

Generally, the clone method of an object, creates a new instance of the same class and copies all the fields to the new instance, and returns it. This is nothing but a shallow copy. Object class provides a clone method and provides support for the shallow copy. It returns ‘Object’ as the type and you need to explicitly cast it to your original object.

Since the Object class has the clone method (protected) you cannot use it in all your classes. The class which you want to be cloned should implement the clone method and overwrite it. It should provide its meaning for the copy or to the least it should invoke the super.clone(). Also, you have to implement a Cloneable marker interface or else you will get CloneNotSupportedException. When you invoke the super.clone() then you are dependent on the Object class’s implementation and what you get is a shallow copy.

Shallow copy vs Deep copy

Deep Copy

When you need a deep copy then you need to implement it yourself. When the copied object contains some other object its references are copied recursively in the deep copy. When you implement deep copy be careful as you might fall for cyclic dependencies. If you don’t want to implement deep copy yourselves then you can go for serialization. It does implements deep copy implicitly and gracefully handling cyclic dependencies.

One more disadvantage with this clone system is that most of the interface / abstract class writers in java forget to put a public clone method. For example, you can take a List. So when you want to clone their implementations you have to ignore the abstract type and use actual implementations like ArrayList by name. This completely removes the advantage and goodness of abstractness.

When implementing a singleton pattern, if its superclass implements a public clone() method, to prevent your subclass from using this class’s clone() method to obtain a copy overwrite it and throw an exception of type CloneNotSupportedException.

Let’s try to implement an example using class “Student” and “Course”, and then we will implement both shallow and deep copy.

public class Student implements Cloneable{

	 int rollno;
	
	 String name;
	
	 Course course;

	public Student(int rollno, String name, Course course) {
		super();
		this.rollno = rollno;
		this.name = name;
		this.course = course;
	}

	@Override
	public String toString() {
		return "Student [rollno=" + rollno + ", name=" + name + ", course=" + course + "]";
	}
	
	protected Object clone() throws CloneNotSupportedException{
		return super.clone();
	}
}
public class Course implements Cloneable{

	 String course1;

	 String course2;

	 String course3;

	public Course(String course1, String course2, String course3) {
		super();
		this.course1 = course1;
		this.course2 = course2;
		this.course3 = course3;
	}

	@Override
	public String toString() {
		return "Course [course1=" + course1 + ", course2=" + course2 + ", course3=" + course3 + "]";
	}
	
	protected Object clone() throws CloneNotSupportedException{
		return super.clone();
	}
}

Observe the following code snippet implementing shallow copy.

public class ShallowCopyTest {

	public static void main(String[] args) throws CloneNotSupportedException {
		Course c1 = new Course("Maths", "Biology", "Physics");
		System.out.println("c1 "+c1);
		Student s1 = new Student(1001, "Tom", c1);
		
		System.out.println("s1 "+s1);
		Student s2 = (Student) s1.clone();
		s2.rollno  = 1002;
		s2.name = "sam";
		
		System.out.println("s2 "+s2);
		
		// Now lets try to change the student object s1 course2
		
		s1.course.course2 = "Chemistry";
		
		// Let see the course value of s2 does the change in s1 reflecting in s2 ?
		System.out.println("s2 after s1 modified "+s2);
	}
}

Output:

c1 Course [course1=Maths, course2=Biology, course3=Physics]

s1 Student [rollno=1001, name=Tom, course=Course [course1=Maths, course2=Biology, course3=Physics]]
s2 Student [rollno=1002, name=sam, course=Course [course1=Maths, course2=Biology, course3=Physics]]

s2 after s1 modified Student [rollno=1002, name=sam, course=Course [course1=Maths, course2=Chemistry, course3=Physics]]

To provide deep copy first we have to update the clone() method in the “Student” class by overriding its implementation. After modification the class will look like as below:

public class Student implements Cloneable {

	int rollno;

	String name;

	Course course;

	public Student(int rollno, String name, Course course) {
		super();
		this.rollno = rollno;
		this.name = name;
		this.course = course;
	}

	@Override
	public String toString() {
		return "Student [rollno=" + rollno + ", name=" + name + ", course=" + course + "]";
	}

	protected Object clone() throws CloneNotSupportedException{
		 Student student = (Student) super.clone();
	     student.course = (Course) course.clone();
	     
		return student;
	}
}

Now run the below code snippet and observe the output.

public class ShallowCopyTest {

	public static void main(String[] args) throws CloneNotSupportedException {
		Course c1 = new Course("Maths", "Biology", "Physics");
		System.out.println("c1 "+c1);
		Student s1 = new Student(1001, "Tom", c1);
		
		System.out.println("s1 "+s1);
		Student s2 = (Student) s1.clone();
		s2.rollno  = 1002;
		s2.name = "sam";
		
		System.out.println("s2 "+s2);
		
		// Now let's try to change the student object s1 course2
		
		s1.course.course2 = "Chemistry";
		System.out.println("s1 after modified "+s1);
		// Let see the course value of s2 does the change in s1 reflecting in s2?
		System.out.println("s2 after s1 modified "+s2);
	}
}

Output:

c1 Course [course1=Maths, course2=Biology, course3=Physics]

s1 Student [rollno=1001, name=Tom, course=Course [course1=Maths, course2=Biology, course3=Physics]]
s2 Student [rollno=1002, name=sam, course=Course [course1=Maths, course2=Biology, course3=Physics]]

s1 after modified Student [rollno=1001, name=Tom, course=Course [course1=Maths, course2=Chemistry, course3=Physics]]
s2 after s1 modified Student [rollno=1002, name=sam, course=Course [course1=Maths, course2=Biology, course3=Physics]]

Recommended Read

Object Cloning in Java
Mutable and immutable objects in java

Reference

Community Doc

Happy Learning !!

Java 8 functional interface with example

We have already discussed, a lot of changes have been introduced in Java 8, like Default and static methods in interface, foreach method in Iterable Interface. Today we will discuss the java 8 functional interface and the annotation.

@FunctionalInterface

Functional interface

An interface with exactly one abstract method will be considered as a functional interface. The annotation @FunctionalInterface can be used to mark it as a functional interface. If an interface has only an abstract method then there is no need to even put the @FunctionalInterface annotation over it.

One of the major benefits of the functional interface is the possibility to use a lambda expression to instantiate them. We can instantiate them using an anonymous class but that code looks bulky.

Java 8 added a new Package java.util.function and the interfaces in this package are annotated with FunctionalInterface. Refer to the below description of the functional interface form Java doc.

Functional interfaces provide target types for lambda expressions and method references. Each functional interface has a single abstract method, called the functional method for that functional interface, to which the lambda expression’s parameter and return types are matched or adapted. Functional interfaces can provide a target type in multiple contexts, such as assignment context, method invocation, or cast context, like:

     // Assignment context
     Predicate<String> p = String::isEmpty;

     // Method invocation context
     stream.filter(e -> e.getSize() > 10)...

     // Cast context
     stream.map((ToIntFunction) e -> e.getSize())...

The Example of a functional interface is the Runnable interface. See the below implementation of the Runnable interface from Java source.

@FunctionalInterface
public interface Runnable {

    public abstract void run();

}

Let’s try to implement the Runnable interface with both anonymous class and with the lambda expression and see the difference.

Using Anonymous class

Thread t = new Thread(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("The anonymous way");
			}
		});
		
		t.start();

Using Lambda expression

Runnable runnable = () ->{
		System.out.println("The lambda way");	
	};
	
	Thread t1 = new Thread(runnable);
	t1.start();

Let see some example of the valid functional interfaces:

(1) The best case will be interface with only one abstract method. Refer below example.

interface I1{
	
	int add(int a, int b);
}
public class MainTest {

	public static void main(String[] args) {

		I1 i = (a, b) -> {
			return a + b;
		};

		System.out.println(i.add(10, 20));
	}

}

// output will:- be the sum of a and b 30

(2) Interface with one abstract method and default method. Refer below example.

@FunctionalInterface
interface I2 {

	int add(int a, int b);
	
	default void display(){
		System.out.println("I am a functional interface");
	}
}

The interface I2 will be a valid functional interface even if you don’t put @FunctionalInterface annotation.

public class MainTest {

	public static void main(String[] args) {

		I2 i = (a, b) -> {
			return a + b;
		};
		int sum =  i.add(10, 20);
		System.out.println("the sum of a and b "+sum);
		
		i.display();
	}

}

/*
output will be:-
sum of a and b 30
I am a functional interface
*/

(3) Interface with one abstract method and with the default and static methods. Refer below example.

@FunctionalInterface
interface I3 {

	int add(int a, int b);
	
	default void display(){
		System.out.println("I am a functional interface");
	}
	
	static void foo(){
		System.out.println("I am a static method in a functional interface ");
	}
}

The interface I3 will be a valid functional interface even if you don’t put @FunctionalInterface annotation.

public class MainTest {

	public static void main(String[] args) {

		I3 i = (a, b) -> {
			return a + b;
		};
		int sum =  i.add(10, 20);
		System.out.println("sum of a and b "+sum);
		
		i.display();
		
		I3.foo();
	}

}

/* 
the output will be:-
the sum of a and b 30
I am a functional interface
I am a static method in a functional interface 
*/

Recommended Read

Java 8 Stream API with examples
Java 8 – Comparison with Lambda
Java 8 method reference with example

Happy Learning !!

Java 8 forEach method in Iterable Interface

It has been Quite a while since Java 8 released. With the release, they have improved some of the existing APIs and added few new features. One of them is Java 8 forEach method in java.lang.Iterable Interface.

The implementation of the forEach method in the Iterable interface is:

default void forEach(Consumer&lt;? super T&gt; action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

Whenever we need to traverse over a collection we have to create an Iterator to iterate over the collection and then we can have our business logic inside a loop for each of the elements inside the collection. We may be greeted with ConcurrentModificationException if it is not implemented properly.

See the below code snippet.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;

public class ForEachExample {

	public static void main(String[] args) {
		List&lt;String&gt; data = new ArrayList&lt;&gt;();
		data.add("New Delhi");
		data.add("New York");
		data.add("Mumbai");
		data.add("London");
		
		Iterator&lt;String&gt; itr = data.iterator();
		while(itr.hasNext()){
		     
		    System.out.println(itr.next());
		       //data.remove(itr.next()); // this line can introduce you to java.util.ConcurrentModificationException.
		}
	}
}

Java 8 has introduced the forEach method in the Iterable interface which takes a java.util.function.Consumer
Object as an input. It helps us write our business logic at a separate location so that we can reuse it.

Let’s see a simple implementation of forEach:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ForEachExample {

	public static void main(String[] args) {
		List&lt;String&gt; data = new ArrayList&lt;&gt;();
		data.add("New Delhi");
		data.add("New York");
		data.add("Mumbai");
		data.add("London");
		
		data.forEach(new Consumer&lt;String&gt;() {
			 
		    @Override
		    public void accept(String t) {
		         
		        System.out.println(t);
		    }
		     
		});
	}
}

The output will be:

New Delhi
New York
Mumbai
London

In the above example, we have created a List of String with 4 elements and then we have iterated over the list using the forEach method. As described earlier forEach method take the Consumer object as input, we have created an anonymous inner class implementation of the Consumer interface and overrides the accept method. In this example, we have kept the business logic inside the anonymous inner class and we can not reuse it. Now let’s make the Consumer implementation separately that can be reused.

To implement Consumer implementation separately create a class that implements the Consumer interface and overrides its accept method as shown below.

class CityConsumer implements Consumer&lt;String&gt;{

	@Override
	public void accept(String t) {
		System.out.println(t);
	}
	
}

Now we can use the CityConsumer with forEach method by just creating an object of CityConsumer class as below.

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ForEachExample {

	public static void main(String[] args) {
		List&lt;String&gt; data = new ArrayList&lt;&gt;();
		data.add("New Delhi");
		data.add("New York");
		data.add("Mumbai");
		data.add("London");
		
		CityConsumer cityConsumer = new CityConsumer();
		data.forEach(cityConsumer);

	}
}

The output will be:

New Delhi
New York
Mumbai
London

Happy Learning !!!

Commonly used methods of Session Interface

The org.hibernate.Session interface is the most used interface in hibernate. It is used to perform the CURD operation. Following are the some commonly used methods of Session Interface.

Required:

  • MySQL 5.1.6
  • Java 8 (jdk 1.8)
  • Hiberante 4.3.5

Dependencies, pom.xml file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>hibernate4</groupId>
  <artifactId>hibernate</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>hibernate</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
  		<groupId>org.hibernate</groupId>
  		<artifactId>hibernate-core</artifactId>
  		<version>4.3.5.Final</version>
  	</dependency>
  	<dependency>
  		<groupId>mysql</groupId>
  		<artifactId>mysql-connector-java</artifactId>
  		<version>5.1.6</version>
  	</dependency>
  </dependencies>
</project>

Let’s create a table and entity class to examine each method in details.

Database Table

CREATE  TABLE `orders` (

  `orderNo` INT NOT NULL AUTO_INCREMENT ,

  `orderBy` VARCHAR(45) NOT NULL ,

  `orderDate` TIMESTAMP NOT NULL ,

  `orderAmount` DECIMAL(16,2) NULL ,

  PRIMARY KEY (`orderNo`) );

Entity class

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name="orders")
public class Orders implements Serializable{

	private static final long serialVersionUID = -7290073664502187027L;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer orderNo;
	
	private String orderBy;
	@Temporal(value = TemporalType.TIMESTAMP)
	private Date orderDate;
	
	private Double order amount;

	public Orders() {
		super();
	}

	public Orders(String orderBy, Date orderDate, Double orderAmount) {
		super();
		this.orderBy = orderBy;
		this.orderDate = orderDate;
		this.orderAmount = orderAmount;
	}


	public Integer getOrderNo() {
		return orderNo;
	}

	public void setOrderNo(Integer orderNo) {
		this.orderNo = orderNo;
	}

	public String getOrderBy() {
		return orderBy;
	}

	public void setOrderBy(String orderBy) {
		this.orderBy = orderBy;
	}

	public Date getOrderDate() {
		return orderDate;
	}

	public void setOrderDate(Date orderDate) {
		this.orderDate = orderDate;
	}

	public Double getOrderAmount() {
		return orderAmount;
	}

	public void setOrderAmount(Double orderAmount) {
		this.orderAmount = orderAmount;
	}

	@Override
	public String toString() {
		return "Orders [orderNo=" + orderNo + ", orderBy=" + orderBy + ", orderDate=" + orderDate + ", orderAmount="
				+ orderAmount + "]";
	}	
}

Create an XML file as “hibernate.cfg.xml” under src/main/resources as below.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_dev</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">root</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.show_sql">true</property>
		<property name="hbm2ddl.auto">update</property>
		<mapping class="com.hibernate.entity.Orders"/>
	</session-factory>
</hibernate-configuration>

Write a class HibernateUtil.java to create the SessionFactory instance.

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtil {

	private static SessionFactory sessionFactory = null;

	private static SessionFactory buildSessionFactory() {
		try {
			Configuration configuration = new Configuration();
			configuration.configure("hibernate.cfg.xml");

			ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
					.applySettings(configuration.getProperties()).build();
			SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
			return sessionFactory;
		} catch (Throwable ex) {
			System.err.println("SessionFactory creation failed." + ex);
			ex.printStackTrace();
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static SessionFactory getSessionFactory() {
		if (sessionFactory == null)
			sessionFactory = buildSessionFactory();
		return sessionFactory;
	}
}

save():

Syntax:

public Serializable save(Object object);

Persist the given transient instance, first assigning a generated identifier or using the current value of the identifier property if the assigned generator is used.

Let’s see the below code snippet to save a transient object into the database.

import java.util.Date;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		
		Orders order = new Orders("Ram", new Date(), 1000.50);
		
		Transaction t = session.beginTransaction();
		
		session.save(order);
		t.commit();
		session.close();	
	}
}

when you run the above code it will insert a record into the database.

Hibernate: insert into orders (orderAmount, orderBy, orderDate) values (?, ?, ?)

We can retrieve the generated ID for the object using the save method. As shown in the save method syntax it returns Serializable.

Let’s modify the above code to retrieve the generated ID.

import java.util.Date;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		
		Orders order = new Orders("kamal", new Date(), 1100.50);
		
		Transaction t = session.beginTransaction();
		
		Integer ID = (Integer) session.save(order);
		System.out.println("generated id is : "+ID);
		t.commit();
		session.close();
		
	}
}

The output of the above code snippet:
output

persist():

Syntax:

public void persist(Object object);

Make a transient instance persistent. As the syntax suggests it does not return any value.

Let’s see the below code snippet to persist a transient object into the database.

import java.util.Date;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		
		Orders order = new Orders("anndy", new Date(), 500.00);
		
		Transaction t = session.beginTransaction();
		
		session.persist(order);
		
		t.commit();
		session.close();
		
	}
}

when you run the above code it will insert a record into the database.

Hibernate: insert into orders (orderAmount, orderBy, orderDate) values (?, ?, ?)

load():

Syntax:

public Object load(Class theClass, Serializable id);

Return the persistent instance of the given entity class with the given identifier, assuming that the instance exists. This method might return a proxied instance that is initialized on-demand when a non-identifier method is accessed. As stated it is used to retrieve an object that you assume exists in the database if the object with the given identifier is not found it will throw “org.hibernate.ObjectNotFoundException”. So this method should not be used to determine whether an object exists or not.

Let’s see the below code snippet to load an object from the database for identifier 2.

import org.hibernate.Session;

import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		
		Orders order = (Orders) session.load(Orders.class, 2);
		System.out.println(order);
		session.close();	
	}
}

When we run this code it will execute a select query and return an object of Orders if it exists or it will throw an Exception mention above.

Hibernate: select orders0_.orderNo as orderNo1_1_0_, orders0_.orderAmount as orderAmo2_1_0_, orders0_.orderBy as orderBy3_1_0_, orders0_.orderDate as orderDat4_1_0_ from orders orders0_ where orders0_.orderNo=?
Orders [orderNo=2, orderBy=kamal, orderDate=2018-11-10 13:51:31.0, orderAmount=1100.5]

get():

Syntax:

public Object get(Class clazz, Serializable id);

Return the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance. (If the instance is already associated with the session, return that instance. This method never returns an uninitialized instance.)

Let’s see the below code snippet to get an object from the database for identifier 1.

import org.hibernate.Session;

import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		
		Orders order = (Orders) session.get(Orders.class, 1);
		System.out.println(order);
		session.close();
		
	}
}

When we run this code it will execute a select query and return an object of Orders if it exists or null.

Hibernate: select orders0_.orderNo as orderNo1_1_0_, orders0_.orderAmount as orderAmo2_1_0_, orders0_.orderBy as orderBy3_1_0_, orders0_.orderDate as orderDat4_1_0_ from orders orders0_ where orders0_.orderNo=?
Orders [orderNo=1, orderBy=Ram, orderDate=2018-11-10 13:44:10.0, orderAmount=1000.5]

update():

Syntax:

public void update(Object object);

Update the persistent instance with the identifier of the given detached instance. If there is a persistent instance with the same identifier, an exception is thrown.

Let’s examine the below code snippet.

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		
		Orders order = (Orders) session.get(Orders.class, 1);
		System.out.println(order);
		
		order.setOrderAmount(2345.00);
		Transaction t = session.beginTransaction();
		session.update(order);
		t.commit();
		System.out.println("order after update :" +order);
		session.close();
	}
}

when you run the above code it will first fetch an object of Orders from the database and then it will execute an update query to update the record with the changes made. See the output of the above code snippet.

Hibernate: select orders0_.orderNo as orderNo1_1_0_, orders0_.orderAmount as orderAmo2_1_0_, orders0_.orderBy as orderBy3_1_0_, orders0_.orderDate as orderDat4_1_0_ from orders orders0_ where orders0_.orderNo=?
Orders [orderNo=1, orderBy=Ram, orderDate=2018-11-10 14:41:33.0, orderAmount=1000.5]
Hibernate: update orders set orderAmount=?, orderBy=?, orderDate=? where orderNo=?
order after update :Orders [orderNo=1, orderBy=Ram, orderDate=2018-11-10 14:41:33.0, orderAmount=2345.0]

saveOrUpdate():

Syntax:

public void saveOrUpdate(Object object);

Either save or update the given instance, depending upon the resolution of the unsaved-value. A transient object will be saved or a detached instance containing a new or updated state will be updated.

Let’s examine the below code snippet.

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();

		Orders order = new Orders("anna", new Date(), 1540.00);
		Transaction t = session.beginTransaction();
		
		session.saveOrUpdate(order);
		
		t.commit();
		
		System.out.println("order after insert:" +order);
		session.close();
		
		order.setOrderAmount(2000.25);
		session = HibernateUtil.getSessionFactory().openSession();
		t = session.beginTransaction();
		
		session.saveOrUpdate(order);
		
		t.commit();
		session.close();
		System.out.println("order after update :" +order);
	}
}

When you run the above code it will insert a record into the database and later it will update the same instance with a new session. See the below output.

Hibernate: insert into orders (orderAmount, orderBy, orderDate) values (?, ?, ?)
order after insert:Orders [orderNo=5, orderBy=anna, orderDate=Sat Nov 10 14:52:55 IST 2018, orderAmount=1540.0]
Hibernate: update orders set orderAmount=?, orderBy=?, orderDate=? where orderNo=?
order after update :Orders [orderNo=5, orderBy=anna, orderDate=Sat Nov 10 14:52:55 IST 2018, orderAmount=2000.25]

merge():

Syntax:

public Object merge(Object object);

Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session.

Let’s examine the below code snippet.

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();

		Orders order = new Orders("tina", new Date(), 1999.00);
		
		Transaction t = session.beginTransaction();
		
		session.save(order);
		
		t.commit();
		
		System.out.println("order after insert:" +order);
		session.evict(order);
		
		order.setOrderAmount(2999.00);
		t = session.beginTransaction();
		order = (Orders) session.merge(order);
		t.commit();
		session.close();
		System.out.println("order after merge :" +order);
	}
}

When you run the above code it will insert the order object. As we have called the evict method of the session, now if we call the merge method it will first load the persistent object from the database and then it will be updated. See the output of the above code snippet.

Hibernate: insert into orders (orderAmount, orderBy, orderDate) values (?, ?, ?)
order after insert:Orders [orderNo=7, orderBy=tina, orderDate=Sat Nov 10 15:20:32 IST 2018, orderAmount=1999.0]
Hibernate: select orders0_.orderNo as orderNo1_1_0_, orders0_.orderAmount as orderAmo2_1_0_, orders0_.orderBy as orderBy3_1_0_, orders0_.orderDate as orderDat4_1_0_ from orders orders0_ where orders0_.orderNo=?
Hibernate: update orders set orderAmount=?, orderBy=?, orderDate=? where orderNo=?
order after merge :Orders [orderNo=7, orderBy=tina, orderDate=Sat Nov 10 15:20:32 IST 2018, orderAmount=2999.0]

delete():

Syntax:

public void delete(Object object);

Remove a persistent instance from the database. The argument may be an instance associated with the receiving Session or a transient instance with an identifier associated with an existing persistent state.

Let’s examine the below code snippet.

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();

		Orders order = new Orders("tina", new Date(), 1999.00);
		
		order.setOrderNo(7); // assigning an existing order no this transient instance. 
		
		Transaction t = session.beginTransaction();
		
		session.delete(order);
		
		t.commit();
		
	}
}

When you run the above code it will delete the record having ID as 7 from the database. See the output of the above code snippet.

Hibernate: delete from orders where orderNo=?

refresh():

Syntax:

public void refresh(Object object);

Re-read the state of the given instance from the underlying database.

Let’s examine the below code snippet.

import org.hibernate.Session;

import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();

		Orders order = new Orders("bill", new Date(), 590.00);
		System.out.println("intial order transient instance "+order);
		
		session.save(order);
		
		session.flush();
		
		session.refresh(order);
		System.out.println("order loaded from the database after refresh "+order);
		
	}	
}

When you run the above code it will fire an insert query on a transient object having any ID as null. When calling the refresh method on the same object we will get the ID. See the output of the above code snippet.

intial order transient instance Orders [orderNo=null, orderBy=bill, orderDate=Sat Nov 10 15:44:52 IST 2018, orderAmount=590.0]
Hibernate: insert into orders (orderAmount, orderBy, orderDate) values (?, ?, ?)
Hibernate: select orders0_.orderNo as orderNo1_1_0_, orders0_.orderAmount as orderAmo2_1_0_, orders0_.orderBy as orderBy3_1_0_, orders0_.orderDate as orderDat4_1_0_ from orders orders0_ where orders0_.orderNo=?
order loaded from the database after refresh Orders [orderNo=9, orderBy=bill, orderDate=2018-11-10 15:44:52.0, orderAmount=590.0]

flush():

Syntax:

public void flush() throws HibernateException;

Force this session to flush. Must be called at the end of a unit of work, before committing the transaction and closing the session. Flushing is the process of synchronizing the underlying persistent store with a persistent state held in memory.

Let’s examine the below code snippet.

import java.util.Date;


import org.hibernate.Session;
import org.hibernate.Transaction;

import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();

		Orders order = new Orders("bill", new Date(), 590.00);
		System.out.println("intial order transient instance "+order);
		
		Transaction t = session.beginTransaction();
		
		session.save(order);
		
		session.flush();
		
		t.commit();
		
		session.close();
	}	
	
}

When you run the above code it will fire insert query when we call session.flush(). At this stage, the persistent object is synced with the database but the object is still to be persisted. The object will only persist when we commit the transaction. This method is useful when we require the ID of a persisting object before it is persisted into the database.

close():

Syntax:

public Connection close() throws HibernateException;

End the session by releasing the JDBC connection and cleaning up. It is not strictly necessary to close the session but you must at least disconnect it.

See the use of the close method in the above-used code snippet.

clear():
Syntax:

public void clear();

Completely clear the session. Evict all loaded instances and cancel all pending saves, updates, and deletions. Do not close open iterators or instances of ScrollableResults.

To use it just called session.clear();

session.clear();

cancelQuery():

Syntax:

public void cancelQuery() throws HibernateException;

Cancel the execution of the current query. This is the sole method of the session which may be safely called from another thread. throws HibernateException if there was a problem canceling the query.

evict():
Syntax:

public void evict(Object object);

Remove this instance from the session cache. Changes to the instance will not be synchronized with the database.

Let’s examine the below code snippet.

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.hibernate.entity.Orders;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		
		Orders order  = new Orders("lisa", new Date(), 2349.90);
		Transaction t = session.beginTransaction();
		session.save(order);
		t.commit();
		System.out.println("order after save is "+order);
		
		session.evict(order);
		System.out.println("order after sesion evict "+order);
		
		t = session.beginTransaction();
		session.save(order);
		t.commit();
		session.close();
	}	
}

When you run the above code it will persist an instance of Orders into the database. Once we call the session.evict() the instance of orders will we be considered as a new instance of orders if we call session.save() on it. See the output of the above code snippet.

Hibernate: insert into orders (orderAmount, orderBy, orderDate) values (?, ?, ?)
order after save is Orders [orderNo=12, orderBy=lisa, orderDate=Sat Nov 10 16:15:43 IST 2018, orderAmount=2349.9]
order after sesion evict Orders [orderNo=12, orderBy=lisa, orderDate=Sat Nov 10 16:15:43 IST 2018, orderAmount=2349.9]
Hibernate: insert into orders (orderAmount, orderBy, orderDate) values (?, ?, ?)

doWork():

Syntax:

public void doWork(Work work) throws HibernateException;

Controller for allowing users to perform JDBC related work using the Connection managed by this Session. As the syntax suggests return type as void it will not return any value. to return value use doReturningWork().

Let’s examine the below code snippet.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.jdbc.Work;

import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction t = session.beginTransaction();
		session.doWork(new Work() {
			String query = "insert into orders (orderAmount, orderBy, orderDate) values (?, ?, ?)";	
			public void execute(Connection connection) throws SQLException {
				PreparedStatement ps = connection.prepareStatement(query);
				ps.setDouble(1, 3999.99);
				ps.setString(2, "addy");
				ps.setTimestamp(3, new Timestamp(new Date().getTime()));
				
				int result = ps.executeUpdate();
				System.out.println("result is "+result);
			}
		});
		t.commit();
		session.close();
	}	
}

When you run the above code it will insert a new record into the database with the given values.

result is 1

doReturningWork():

Syntax:

public  T doReturningWork(ReturningWork work) throws HibernateException;

Controller for allowing users to perform JDBC related work using the Connection managed by this Session. After execution returns the result.

Let’s examine the below code snippet.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.jdbc.ReturningWork;
import com.hibernate.util.HibernateUtil;

public class SessionInterfaceMethods {

	public static void main(String[] args) {
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction t = session.beginTransaction();
		
		session.doReturningWork(new ReturningWork<Double>() {

			public Double execute(Connection connection) throws SQLException {
				PreparedStatement ps = connection.prepareStatement("select orderAmount from orders where orderNo = 6");
				ResultSet rs = ps.executeQuery();
				rs.next();
				Double orderAmount = rs.getDouble("orderAmount");
				System.out.println("orderAmount "+orderAmount);
				return orderAmount;
			}
			
		});
		t.commit();
		session.close();
	}	
}

When you run the above code it will print the output

orderAmount 1780.0

This is very useful when we have to call a stored procedure that returns some values.

That’s it in commonly used methods of session interface.

Read more about hibernate.

Reference https://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/Session.html

HAPPY LEARNING !!

java.util.ConcurrentModificationException

java.util.ConcurrentModificationException

This is a very common Exception that occurred while working with java collection classes. Java collection is fail-fast, which means any modification made while traversing over it using Iterator, the iterator.next() method will throw ConcurrentModificationException. Concurrent modification exceptions can occur in the case of multi-threaded as well as in the single-threaded environment.

Below are the common cases of Concurrent modification exception and how to avoid them.
Using List

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class JavaConcurrentModificationException {

	void withListUsingForLoop(){
		List<String> values = new ArrayList<>();
		values.add("java");
		values.add("oracle");
		values.add(".net");
		values.add("php");
		values.add("python");
		values.add("perl");
		
		System.out.println("with for each loop");
		for(String str : values){ // this line will throw Concurrent modification exception in next iteration.
			System.out.println(str);
			values.remove(str); 
		}
		
	}

	void withListUsingIterator(){
		List<String> values = new ArrayList<>();
		values.add("java");
		values.add("oracle");
		values.add(".net");
		values.add("php");
		values.add("python");
		values.add("perl");
		
		System.out.println("with iterator");
		Iterator<String> itr = values.iterator();
		while(itr.hasNext()){ // this line will throw Concurrent modification exception in next iteration.
			String value = itr.next();
			System.out.println(value);
			values.remove(value); 
		}
	}
	
	void withListUsingSubList(){
		List<String> values = new ArrayList<>();
		values.add("java");
		values.add("oracle");
		values.add(".net");
		values.add("php");
		values.add("python");
		values.add("perl");
		System.out.println("with sub list");
		List<String> subList = values.subList(1, 3);

		System.out.println(values +" "+subList);
		values.add("my sql");
		
		System.out.println(values +" "+subList); // this line will throw Concurrent modification exception. 
		// comment above line and run										
		for(String str : subList){ // this line will throw Concurrent modification exception. reason same as above
			System.out.println(str);
		}
		
	}
	
	public static void main(String[] args) {
		JavaConcurrentModificationException jc = new JavaConcurrentModificationException();
		// call each method one by one
                jc.withListUsingForLoop();
		//jc.withListUsingIterator();
		//jc.withListUsingSubList();
		
	}
}

Note: The reason behind the “Concurrent modification exception” in the sub list, is According to the ArrayList subList documentation, structural modifications are allowed only on the list returned by the subList method. All methods on the returned list first check to see if the actual modCount of the backing list is equal to its expected value and throw a ConcurrentModificationException if it is not.

Using Map:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

public class JavaConcurrentModificationException {

	
	void withMapUsingIterator(){
		Map<String, Integer> map = new HashMap<>();
		
		map.put("java", 1);
		map.put("oracle", 2);
		map.put(".net", 3);
		map.put("php", 4);
		
		Iterator<Entry<String, Integer>> itr = map.entrySet().iterator();
		while(itr.hasNext()){
			String key = itr.next().getKey(); // this line wil throw Concurrent modification exception
			Integer value = map.get(key);
			System.out.println(key + " "+value );
			map.remove(key);
			
		}
		
	}
	
	void withMapUsingForLoop(){
		Map<String, Integer> map = new HashMap<>();
		
		map.put("java", 1);
		map.put("oracle", 2);
		map.put(".net", 3);
		map.put("php", 4);
		for(Entry<String, Integer> entry : map.entrySet()){  // this line will throw Concurrent modification exception in next iteration.  
			System.out.println(entry.getKey() +" "+entry.getValue());
			map.remove(entry.getKey());
			
		}
		// comment above loop to check this
		for(String key : map.keySet()){ // this line will throw Concurrent modification exception in next iteration.  
			System.out.println(key +" "+map.get(key));
			map.remove(key);
			
		}
	}
	
	public static void main(String[] args) {
		JavaConcurrentModificationException jc = new JavaConcurrentModificationException();
		// run below line one b one
		jc.withMapUsingIterator();
		jc.withMapUsingForLoop();
		
	}
}

Output

Exception in thread "main" java 1
java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
	at java.util.HashMap$EntryIterator.next(HashMap.java:1471)
	at java.util.HashMap$EntryIterator.next(HashMap.java:1469)

Okay, we are done with some causes of “ConcurrentModificationException” let’s check how we can avoid this when we are working with collection classes.

import java.util.*;

public class JavaConcurrentModificationException {

	void avoidConcurrentModificationExceptionUsingListAndLoop(){
		List<String> values = new ArrayList<>();
		values.add("java");
		values.add("oracle");
		values.add(".net");
		values.add("php");
		values.add("python");
		values.add("perl");
		
		System.out.println("with for each loop");
		for(int i = 0; i < values.size(); i++){
			System.out.println(values.get(i));
			values.remove(i);
			System.out.println("after removal "+values);
			
		}
	}
	void avoidConcurrentModificationExceptionUsingListAndIterator(){
		List<String> values = new ArrayList<>();
		values.add("java");
		values.add("oracle");
		values.add(".net");
		values.add("php");
		values.add("python");
		values.add("perl");
		
		System.out.println("with iterator");
		Iterator<String> itr = values.iterator();
		while(itr.hasNext()){
			String value = itr.next();
			System.out.println(value);
			itr.remove(); //  But in this case you can only remove same object returned by itrator.next()
			System.out.println("after removal "+values);
		}
		
		
	}
	
	public static void main(String[] args) {
		JavaConcurrentModificationException jc = new JavaConcurrentModificationException();
		jc.avoidConcurrentModificationExceptionUsingListAndLoop();
		jc.avoidConcurrentModificationExceptionUsingListAndIterator();
	}
}

While working java.util.Map use Iterator remove method or ConcurrentHashMap.

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

public class JavaConcurrentModificationException {

	void avoidConcurrentModificationExceptionUsingMap(){
		// use ConcurrentHashMap, or Iterator.remove() method
		Map<String, Integer> map = new HashMap<>();
		
		map.put("java", 1);
		map.put("oracle", 2);
		map.put(".net", 3);
		map.put("php", 4);
		System.out.println("map size before removal is "+ map.size());
		Iterator<Entry<String, Integer>> itr = map.entrySet().iterator();
		while(itr.hasNext()){
			String key = itr.next().getKey();
			Integer value = map.get(key);
			System.out.println(key + " "+value );
			// map.remove(key); replace this line with line below 
			
			itr.remove(); //But this line only allow removal of same item returned by itrator.next()
		}
		System.out.println("map size after removal is "+map.size());
		
		System.out.println("Using ConcurrenthashMap");
		
		Map<String, Integer> conMap = new ConcurrentHashMap<>();
		
		conMap.put("java", 1);
		conMap.put("oracle", 2);
		conMap.put(".net", 3);
		conMap.put("php", 4);
		System.out.println("conMap size before removal is "+ conMap.size());
		Iterator<Entry<String, Integer>> conMapItr = conMap.entrySet().iterator();
		while(conMapItr.hasNext()){
			String key = conMapItr.next().getKey();
			Integer value = conMap.get(key);
			System.out.println(key + " "+value );
			conMap.remove(key); // this line will now not throw ConcurrentModificationException 
			
			//conMapItr.remove(); // you can use this as well.
			conMap.put("perl", 5); // this line will not throw ConcurrentModificationException
		}
		System.out.println("conMap size after removal is "+conMap.size());
	}
	
	
	public static void main(String[] args) {
		JavaConcurrentModificationException jc = new JavaConcurrentModificationException();
		jc.avoidConcurrentModificationExceptionUsingMap();
	}
}

Recommended Read:

Java Exception in detail with example

How to create Java Custom Exception?

Happy Learning !!

HTTP Request Methods and specification

HTTP defines a set of request methods to specify the desired action to be performed for a given resource. These request methods are sometimes referred to as HTTP verbs. Each of them implements a different semantic, but some common features are shared by a group of them: e.g. a request method can be safe, idempotent, or cacheable.

Http Request Method

Use Request Methods to map CRUD (create, retrieve, update, delete) operations to HTTP requests.

Method DescriptionExample
GETGET is used to Retrieve information. GET requests must be safe and idempotent, meaning regardless of how many times it repeats with the same parameters, the results has to be same.Retrieve an Employee with an ID of 1:
GET /employee/1
POSTThe POST method is used to submit an entity to the specified resource, often used to create a new entity, but it can also be used to update an entity.Create a new Employee:
POST /addresses
PUTThe PUT method replaces all current representations of the target resource with the request payload and it is idempotent.
Idempotency is the main difference between PUT versus a POST request.
Modify the Employee with an ID 1:
PUT /addresses/1
DELETEThe DELETE method delete the specified resource. Delete an employee having ID 1:
DELETE /addresses/1
OPTIONSThe OPTIONS method is used to describe the communication options for the target resource.
PATCHThe PATCH method Update only the specified fields of an entity at a URI. A PATCH request is also idempotent.PATCH /addresses/1

Specifications
RFC 7231, section 4: Request methods Specifies GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE.

RFC 5789, section 2: Patch method Specifies PATCH.

Recommended Read
Rest Web Services

Happy Learning !!

Object oriented programming with Java

Object-oriented programming with Java

Object oriented programming with Java

OOPs (Object-oriented programming) is a programming paradigm based on the concept of objects, which can contain data, in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).

Class: Class is A template that specifies the state (property or field) and behavior (function Or method) that objects of its type will support. Refer below to a very simple class definition a

public class Test{
	
	int number = 10;
	
	public void print() {
		System.out.println(number);
	}
}

Object: During run-time, when the Java Virtual Machine (JVM) encounters the new keyword, it will use the appropriate class to make an object of that class. That object will have its state, and access to all of the behaviors defined by its class. testObj is an Object of class Test.

Test testObj = new Test();

Abstraction: Objects in object-oriented programming language provide an abstraction that hides the internal implementation details. You just need to know which methods of the object are available to call and which input parameters are needed to trigger a specific operation.

In simple words, you don’t need to understand how a method is implemented inside a class and which kinds of actions it has to perform to create the expected result. Abstraction always refers to the implementation of a class. In Java, we can achieve abstraction by declaring a class abstract or using the interface.

Inheritance: It is a concept to implement reusability. When you want to create a class and there is a class that already has the code you want, here you can drive your new class from the existing class. In doing this you can reuse the behavior and state of that class. Read inheritance in detail.

Encapsulation: It is the concept of object-oriented programming that consists of minimizing the interdependence between classes and it is typically implemented through information hiding.

The beauty of encapsulation is the power of changing things without affecting its users.

In an object-oriented programming language like Java, you achieve encapsulation by hiding details using the accessibility modifiers (public, protected, private, plus no modifier which implies package-private). With these levels of accessibility, you control the level of encapsulation, the less restrictive the level, the more expensive change is when it happens and the more coupled the class is with other dependent classes (i.e. user classes, subclasses). Therefore, the goal is not to hide the data itself, but the implementation details on how this data is manipulated.

Encapsulation is a mechanism where you don’t restrict access to properties of a class but provide a contract on how others will use it. Encapsulation is not data hiding encapsulation leads to data hiding.

it is used to refer to one of two notations.

  • Restricting direct access to some of the object components.
  • Bundling of data with methods or functions operating on them.

Polymorphism: An Object can take more than one form. The most common use of polymorphism is when a parent class reference is used to refer to a child class object. Any Java object that can pass more than one IS-A relationship can be considered as polymorphic.

There are two types of polymorphism:

  • Compile-time polymorphism
  • Run time polymorphism

Compile-time polymorphism is when an overridden method is called using a child class reference. In this case, during the compile time the compiler checks if the overridden method is present in there or not.

Run time polymorphism means when the call to an overridden method is resolved during run time rather than compile time. In this case, an overridden method is called through the reference variable of the base class. The determination of method call is based on the object referred to by the reference variable.

Let’s understand it with an example.

Create a class Animal.java

public class Animal {

	public void eat(){
		System.out.println("Animal eat");
	}
}

Create a class Dog.java which extends Animal.java

public class Dog extends Animal{

	public void eat(){
		System.out.println("Dog eat");
	}
}

create a class CompileTimeExample.java as shown below and run it.

public class CompileTimeExample {

	public static void main(String[] args) {
		Dog d = new Dog();
		d.eat();
	}
}

The output will be:

Dog eat

Key point: In this case, the method of Dog class will be called and the compiler will check if the eat method is present inside Dog class or not, which is not the case in run time polymorphism.

create a class RunTimeExample.java as shown below and run it.

public class RunTimeExample {

	public static void main(String[] args) {
		Animal a = new Dog();
		a.eat();
	}
}

The output will be:

Dog eat

Key Point: In this case, we have created a reference variable of Base class Animal but it is assigned to an object of child class dog. During compilation, the compiler will check if the eat method is Available inside the Animal class or not. However, during the execution, JVM call eat method of child (Dog) class. Here the call to an overridden method is defined during run time.

Recommended Read

Class-loader in Java

Reference

wiki

Happy Learning !!