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

Understanding and preventing memory leaks in Java

For any developer, memory should be one of the most precious resources to think of while writing a program. A program can be said to be memory efficient when it consumes as little memory as possible when in operation but still doing what it was designed to do. So, before write code think of memory uses, do you know What happens when a Java object is created?

What is a Memory Leak?

In simple words, memory leak means unused memory that the garbage collectors can not reclaim.

A memory leak occurs when objects are no longer being used by the application, but the garbage collector is unable to clear them from working memory. This is a serious problem because these objects hold the memory that could otherwise be used by other parts of the program. With time, this piles up and leads to a degradation in system performance over time.

Garbage Collection in Java

One of the coolest features of Java is its automatic memory management. The Garbage Collection is a program that implicitly takes care of memory allocation and deallocation. It’s an effective program and can handle the majority of memory leaks that are likely to occur. However, it’s not infallible. Memory leaks can still sneak up and start taking up precious resources and, in worst cases, result in the java.lang.OutOfMemoryError.

It’s worth mentioning that an OutOfMemoryError is not always because of memory leaks. At times, it could be poor code practices like loading large files in memory.

The three common causes of memory leaks?

  • Misused static fields
  • Un closed streams
  • Un closed connections

Misused static fields

Static fields live in the memory as long as the class that owns them is loaded in the JVM, which means there are no instances of the class in the JVM, at this point, the class will be unloaded and the static field will be marked for garbage collection. But the catch here is, the static classes can live in the memory forever.

Consider the following code:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class StaticDemo {
public static List&lt;Integer&gt; list = new ArrayList&lt;&gt;();

public void populateList() {
for (int i = 0; i &lt; 10000000; i++) {
   list.add(new Random().nextInt());
}
}
public static void main(String[] args) {
  new StaticDemo().populateList();
}
}

This is a simple and small code snippet, we have a static List and we added values into it. But If we see the declaration of the list we have used static in front of it.  That’s the problem, the memory occupied by this list will be in use until the program finishes its execution even though the operations on the list are already completed.

To avoid this mistake, Minimize the use of static fields in your application.

Un closed streams

Till now we have understood memory leak is when code holds a reference to an object and the garbage collector can’t claim that object. But, a closed stream object is not memory unless it holds a reference of an unclosed stream.

Usually, the operating system limits how many open files (while using FileInputStream) an application can have. So, if such streams are not closed and the garbage collector may take some to claim these objects, it is also a case of the leak but not particularly a memory leak.

Refer to the following code snippet:

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;

public class OpenStreamDemo {

    public static void main(String[] args) throws IOException {
        URL url = new URL("http://ergast.com/api/f1/2004/1/results.json");
        ReadableByteChannel rbc = Channels.newChannel(url.openStream());
        FileOutputStream outputStream = new FileOutputStream("/");
        outputStream.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
    }
}

Here the unclosed FileOutputStream and ReadableByteChannel will cause potential issues. The solution to this problem would be closing these stream objects once they are used and not require further. Or use java to try with resources wherever allowed.

rbc.close();
outputStream.close();

Un closed connections

The frequent mistake in Java programming is, developer forgot to close the database connections.  Having an unclosed database connection can give you a tough time in production and they are difficult to replicate in local environments.

Refer to the below code snippet:

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class OpenConnectionDemo {

    public static void main(String[] args) {
        try {
            List&lt;String&gt; names = fetchUsersName("foo", "bar");
            names.forEach(System.out::println);

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static List&lt;String&gt; fetchUsersName(String username, String password) throws SQLException {
        List&lt;String&gt; names = new ArrayList&lt;&gt;();
        Connection con = DriverManager.getConnection("jdbc:myDriver:devDB",
                username,
                password);

        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT first_name, last_name FROM users");

        String firstName = "";
        String lastName = "";

        while (rs.next()) {
            firstName = rs.getString("first_name");
            lastName = rs.getString("last_name");
            names.add(firstName + " " + lastName);
        }
        return names;
    }
}

Here every resource is leaking. Here we could have use try-catch and finally, and inside the finally block we can close

stmt.close();
con.close();

Here is the complete code for the fetchUsersName method.

public static List&lt;String&gt; fetchUsersName(String username, String password) throws SQLException {
    Statement stmt = null;
    Connection con = null;
    List&lt;String&gt; names = new ArrayList&lt;&gt;();
    try {

        con = DriverManager.getConnection("jdbc:myDriver:devDB",
                username,
                password);

        stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT first_name, last_name FROM users");

        String firstName = "";
        String lastName = "";

        while (rs.next()) {
            firstName = rs.getString("first_name");
            lastName = rs.getString("last_name");
            names.add(firstName + " " + lastName);
        }
    }catch (SQLException se){
        se.printStackTrace();
    }finally {
        stmt.close();
        con.close();
    }
    return names;
}

Or we can use try with resources like below.

public static List&lt;String&gt; fetchUsersName(String username, String password) throws SQLException {
    List&lt;String&gt; names = new ArrayList&lt;&gt;();
    try (Connection con = DriverManager.getConnection("jdbc:myDriver:devDB",username,password);
         Statement stmt = con.createStatement();
    ){
        ResultSet rs = stmt.executeQuery("SELECT first_name, last_name FROM users");

        String firstName = "";
        String lastName = "";

        while (rs.next()) {
            firstName = rs.getString("first_name");
            lastName = rs.getString("last_name");
            names.add(firstName + " " + lastName);
        }
    }catch (SQLException se){
        se.printStackTrace();
    }
    return names;
}

We can also use ORM like hibernate or jooq which provides easier and more maintainable resource handling.

So the take away from this post are:

  1. Be careful while using static fields.
  2. Make sure to close the stream and connection or use try with resources.
  3. Use ORM if your application allows.

 

Happy Learning !!!

Java bitwise operators with example

This tutorial will discuss Java bitwise operators with examples.

Like many other operators, Java defines several bitwise operators as well. They can be applied to the integer types, long, int, short, char, and byte to perform the bit-level operation.

Bitwise operators: Following are the bitwise operators.

  • Bitwise OR (|)
  • Bitwise AND (&)
  • Bitwise XOR (^)
  • Bitwise Complement (~)

These operators work with integer data types only. However, the computer understands the binary number system, hence to perform any operation bitwise operators require the given integer in form of binary internally. So to understand these operator understandings of conversion to binary number is a must.

Let’s take a brief overview of the binary conversion. Binary number work on base-2. where any number will be represented in the form of zero and one. The easiest way to convert any number into binary is to divide the number by 2 as binary numbers work on base 2 and keep track of the reminder. Once the division is completed write the reminder in the backward direction. The last reminder will be the first digit.

Consider the following example where we will convert 7 into binary.

binary conversion of 7

Let’s try another number 25.

binary conversion of 25

1. Bitwise OR (|): This operator operates on two operands. It compares corresponding bits of two operands, if either of the bit is one (1) it gives one otherwise zero (0).

12 = 00001100 (in binary)
| 25 = 00011001 (in binary)

--------------------------
00011101 (in binary) = 29 ( in decimal)
----------------------------------------

2. Bitwise AND (&): This operator also operates on two operands. It compares corresponding bits of two operands, if both the bits are one (1) it gives one otherwise zero (0).

12 = 00001100 (in binary)
& 25 = 00011001 (in binary)

---------------------------------
00011101 (in binary) = 21 ( in decimal)
---------------------------------------

3. Bitwise XOR (^): This operator also operates on two operands. It compares corresponding bits of two operands, It gives one if corresponding bits are different otherwise zero. It works in contrast to Bitwise OR (|) operators.

12 = 00001100 (in binary)
^ 25 = 00011001 (in binary)

---------------------------------
00010101 (in binary) = 29 ( in decimal)
---------------------------------------

4. Bitwise Complement (~): This operator operates on only one operand. It inverts every bit pattern zero to one and vice versa.

The unary bitwise complement operator “~” inverts a bit pattern; it can be applied to any of the integral types, making every “0” a “1” and every “1” a “0”. For example, a byte contains 8 bits; applying this operator to a value whose bit pattern is “00000000” would change its pattern to “11111111”.

Recommended Read

Object oriented programming with Java
Class loaders in Java, types of the class loader

Happy Learning !!

Java 8 Stream API with examples

What is the stream?

Java Stream API

Streams are wrappers around a data source, which allows us to operate with that data source and making bulk processing convenient and fast. A stream represents a sequence of objects from a source, which supports aggregate operations.

The following are the characteristics of a Stream:

The sequence of elements: A stream provides a set of elements of a specific type in a sequential manner. A stream gets/computes elements on demand. It never stores the elements.

Source: Stream takes Collections, Arrays, or I/O resources as an input source.

Aggregate operations: Stream supports aggregate operations like filter, map, limit, reduce, find, match, and so on.

Pipelining: Most of the stream operations return stream itself so that their result can be pipelined. These operations are called intermediate operations and their function is to take input, process them, and return output to the target. collect() method is a terminal operation that is normally present at the end of the pipelining operation to mark the end of the stream.

Automatic iterations: Stream operations do the iterations internally over the source elements provided, in contrast to Collections where explicit iteration is required.

Let’s see a few ways to obtain a stream:

    1. Using existing Array
int [] arr = new int[] {1,2,3,4,5,6,7,8,9,10};
		
Stream.of(arr);

    1. Using existing Collection
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

System.out.println("List Stream\n");
list.stream().forEach(System.out::println);

Set<Integer> set = new HashSet<>(list);

System.out.println("\nSet Stream\n");		
set.stream().forEach(System.out::println);

Map<Integer, String> map = new HashMap<>();

map.put(1, "one");
map.put(2, "two");
map.put(3, "three");

System.out.println("\nMap Stream\n");
map.entrySet().stream().forEach(System.out::println);

    1. Stream from individual objects using Stream.of()
Stream.of(1,2,3,4,5,6);
    1. Using Stream.builder()
Stream.Builder<String> builder = Stream.builder();
builder.accept("welcome");
builder.accept("to");
builder.accept("Java");
builder.accept("8");

Stream<String> stream = builder.build();

stream.forEach(System.out::println);

Stream Operations: Now let’s try some common usages and operations we can perform on and with the help of stream API.

forEach:

forEach() is the simplest and most common operation, it loops over the stream elements, calling the supplied function on each element. You can refer to the above code block to see the uses of foreach(). This method is so common that is has been added directly in Iterable, Map, etc. Observe the following code snippet.

import java.util.Arrays;
import java.util.List;

public class StreamDemo {

	public static void main(String[] args) {
		List<String> cities = Arrays.asList("Delhi","Mumbai","New York","London");
		
		System.out.println("===== Conventional way of looping the list =====");
		for(int i =0 ; i< cities.size() ; i++){
			System.out.println(cities.get(i));
		}
		
		System.out.println("===== Using for each loop =====");
		for(String str : cities){
			System.out.println(str);
		}
		
		System.out.println("===== Using stream and method reference =====");
		cities.stream().forEach(System.out::println);
		
		System.out.println("===== Using stream and lambda =====");
		cities.stream().forEach(city ->{
			System.out.println(city);
		});
	}
}

Once you execute this the output will as below:

===== Conventional way of looping the list =====
Delhi
Mumbai
New York
London
===== Using for each loop =====
Delhi
Mumbai
New York
London
===== Using stream and method reference =====
Delhi
Mumbai
New York
London
===== Using stream and lambda =====
Delhi
Mumbai
New York
London

Similar to forEach() we can also use a stream to perform many more tasks. Like filtering the data, getting count, finding distinct elements, replacing items with mapping new values, etc. Observe the below code snippet, where we are filtering the cities starting with ‘D’ from the city list.

List<String> cities = Arrays.asList("Delhi","Mumbai","New York","London","Dublin");
		
List<String> startingWithD = cities.stream().filter(c -> c.startsWith("D")).collect(Collectors.toList());
		
System.out.println("City name start with d "+startingWithD);

// Output:
City name start with d [Delhi, Dublin]

Recommended Read:

Java 8 method reference with example
Java 8 Predicates
Java 8 forEach method in Iterable Interface
Java 8 forEach method in Iterable Interface
Java 8 Default and Static method in Interface
Java 8 – Comparison with Lambda

References:

Java 8 Stream

Java try with resources statement

Java Exception handling try with resources statement.

Similar to Multi-catch introduced in Java 7 another enhancement made is the try-with-resources Statement.

Earlier the resources need to be close inside the try{ …. } block. But since Java 7 this can be using try-with-resources Statement.

As per the oracle doc

The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

See the below code snippet before Java 7.

public class TryWithResourceExample {

    public static void main(String[] args) {
        readFile("/home/input.txt");
    }

    static String readFile(String path) {
        File file = null;
        try {
            StringBuilder sb = new StringBuilder();
            file = new File(path);
            Scanner sc = new Scanner(file);
            while(sc.hasNextLine()) {
                
                sb.append(sc.nextLine());
            }
            sc.close();
            
            return sb.toString();
            
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

The above code can be rewritten using the try with a resource statement like the below.

public class TryWithResourceExample {

    public static void main(String[] args) {
        readFile("/home/input.txt");
    }

    static String readFile(String path) {
        StringBuilder sb = new StringBuilder();
        
        try (Scanner sc = new Scanner(new File(path))){
            
            while(sc.hasNextLine()) {
                sb.append(sc.nextLine());
            }
            
        }catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
}

The try with the resource can also be used with multiple closeable resources. Observe the following code snippet.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;

public class TryWithResourceExample {

    public static void main(String[] args) {
        readFile("/home/inputfile.txt");
    }

    static void readFile(String path) {
        
        try (InputStream i = new FileInputStream(new File(path)); 
             BufferedReader reader = new BufferedReader(new InputStreamReader(i));    
            ){
            
            System.out.println("File content is : "+reader.readLine());
            
        }catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}

Point to remember: Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used inside the try with resource statement.

For Objects that do not implement AutoCloseable, the compiler will alert the following error.

The resource type {Resource name} does not implement java.lang.AutoCloseable

Recommended read:

Java Exception in detail with example
How to create custom Java Exception?

Happy Learning !!

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 !!

How to make a Java collection unmodifiable?

As array support, fixed-size data and the size has to be calculated during the array initialization programming languages invented collections to overcome the limitation of the array. But as the use of collections increases the requirements also changed. i.e. A collection that has been created should not allow any modification to it. This is the need, which introduced the concept of unmodifiable collections.

Convenience static factory methods on the List, Set, and Map interfaces let you easily create unmodifiable lists, sets, and maps.

A collection is considered unmodifiable if elements cannot be added, removed, or replaced. After you create an unmodifiable instance of a collection, it holds the same data as long as a reference to it exists.

A modifiable collection must maintain bookkeeping data to support future modifications. This adds overhead to the data that is stored in the modifiable collection. An unmodifiable collection does not need this extra bookkeeping data. Because the collection never needs to be modified, the data contained in the collection can be packed much more densely. Unmodifiable collection instances generally consume much less memory than modifiable collection instances that contain the same data.

So when to use an unmodifiable collection?

Whether to use an unmodifiable collection or a modifiable collection depends on the data in the collection.
An unmodifiable collection provides space efficiency benefits and prevents the collection from accidentally being modified, which might cause the program to work incorrectly. An unmodifiable collection is recommended for the following cases:

  • Collections that are initialized from constants that are known when the program is written.
  • Collections that are initialized at the beginning of a program from data that is computed or is read from something such as a configuration file.

For a collection that holds data that is modified throughout the program, a modifiable collection is the best choice. Modifications are performed in-place so that incremental additions or deletions of data elements are quite inexpensive. If this were done with an unmodifiable collection, a complete copy would have to be made to add or remove a single element, which usually has unacceptable overhead.

Note: Making any change to the unmodifiable collection will cause “java.lang.UnsupportedOperationException”.

Let’s try an example to create an unmodifiable collection.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class UnModifiableCollection {

	public static void main(String[] args) {
		List<String> list = new ArrayList<>(Arrays.asList("Temp","Dist","Demt","bin","Hello")) ;
		
		System.out.println("print 1 "+list);
		
		list.add("check");
		
		System.out.println("print 2 "+list);
		
		list = Collections.unmodifiableList(list);
		
		list.add("set"); // This line will prompt the Exception

		// This also creates fixed-size list backed by an array.
	    List<String> unmodifiable = Arrays.asList("Temp","Dist","Demt","bin","Hello"); 
	     
	     // unmodifiable.add("3232"); // Even this line will also prompt the same Exception. Uncomment it to verify. 

	}
}

If you run the above program the output will be like:

print 1 [Temp, Dist, Demt, bin, Hello]
print 2 [Temp, Dist, Demt, bin, Hello, check]
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.Collections$UnmodifiableCollection.add(Collections.java:1055)
	at UnModifiableCollection.main(UnModifiableCollection.java:21)

The java.util.Collections class offers the following methods to create unmodifiable collections.

List of methods provided by Collections class to create unmodifiable collection

From Java 11 onward we can create an unmodifiable collection using the Java Stream API.

The Streams library includes a set of terminal operations known as Collectors. A Collector is most often used to create a new collection that contains the elements of the stream. The java.util.stream.The collectors class has Collectors that create new unmodifiable collections from the elements of the streams.
If you want to guarantee that the returned collection is unmodifiable, you should use one of them toUnmodifiable- collectors. These collectors are:

Collectors.toUnmodifiableList()
Collectors.toUnmodifiableSet()
Collectors.toUnmodifiableMap(keyMapper, valueMapper)
Collectors.toUnmodifiableMap(keyMapper, valueMapper, mergeFunction)

Recommended Read

ArrayList vs LinkedList
Java 8 Default and Static method in Interface

Happy Learning !!

Cannot be cast to java.lang.Comparable

Problem: java.lang.ClassCastException: com.coderdesks.basic.Orders cannot be cast to java.lang.Comparable

Exception in thread "main" java.lang.ClassCastException: com.coderdesks.basic.Orders cannot be cast to java.lang.Comparable
	at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
	at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
	at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
	at java.util.Arrays.sort(Arrays.java:472)
	at com.coderdesks.basic.ComparatorVsComparable.main(ComparatorVsComparable.java:25)
	

Reason:
When we sort array or collection of primitive or wrapper classes it works fine. The reason for that is that these classes have implemented a Comparable interface. But when we try to sort an array of the custom object which does not implement a comparable interface you will face this exception.

Solution:
To resolve this exception implements the Comparable interface and override the compareTo () method just like we have changed the Orders class as shown below.

package com.coderdesks.basic;

public class Orders implements Comparable<Orders>{

	private int orderId;
	
	private double amount;
	
	private String orderBy;

	public Orders(){
		
	}

	public Orders(int orderId, double amount, String orderBy) {
		super();
		this.orderId = orderId;
		this.amount = amount;
		this.orderBy = orderBy;
	}

	@Override
	public String toString() {
		return "Orders [orderId=" + orderId + ", amount=" + amount + ", orderBy=" + orderBy + "]";
	}

	@Override
	public int compareTo(Orders o) {
		return (this.orderId - o.orderId);
	}
}

Recommended Read

Comparable and Comparator.
Java Exception in detail with example

Happy Learning !!

Comparable and Comparator in Java with example

Comparable and Comparator in Java

In any programming language always there is a need to sort the elements of an array or a collection. We can sort array or collection of primitive and wrapper classes in natural order where the number will be sorted in ascending order and the string will be sorted in alphabetic order. But when there is a requirement to sort the custom object array or collection we cannot sort them without providing a sorting mechanism.

Observe the below code snippet where we will be able to sort an array of “int” using Arrays.sort() method. But when we supply an array of custom objects to Arrays.sort() it throws an exception. Read more about Exception.

package com.coderdesks.basic;

import java.util.Arrays;

public class ComparatorVsComparable {

	public static void main(String[] args) {
		
		// primitive array
		int [] numbers = {19,34,2,5,1,4,8,37,21};
		Arrays.sort(numbers);
                System.out.print("int [] after sort ");
		for(int i : numbers){
			System.out.print(i);
			System.out.print(" ");
		}
		System.out.println();
		
		System.out.println("sorting cusotm object array start");
		// custom object array
		Orders [] orders = {
				new Orders(212,2000.40, "Tom"),
				new Orders(132,2999.00, "Sam"),
				new Orders(245,2070.10, "Mark"),
				new Orders(653,2020.33, "Calvin")
		};
		
		Arrays.sort(orders);
		for(Orders order : orders){
			System.out.println(order);
			
		}
	}	
}

Output:

int [] after sort 1 2 4 5 8 19 21 34 37 

sorting custom object array start

Exception in thread "main" java.lang.ClassCastException: com.coderdesks.basic.Orders cannot be cast to java.lang.Comparable
	at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
	at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
	at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
	at java.util.Arrays.sort(Arrays.java:472)
	at com.coderdesks.basic.ComparatorVsComparable.main(ComparatorVsComparable.java:28)

To solve these problems Java provides two interfaces java.lang.Comparable and java.util.Comparator.

public interface Comparable<T> {
   public int compareTo(T o);
}

public interface Comparator<T> {

int compare(T o1, T o2);

boolean equals(Object obj);

}

Let’s understand these interfaces in more detail.

Comparable:

Java provides a Comparable interface that should be implemented by any custom class if we want to use Arrays or Collections sorting methods to sort the elements.

The Comparable interface has the compareTo(T o) method which is used for sorting. We should override this method in such a way that it returns a negative integer, zero, or a positive integer if “this” object is less than, equal to, or greater than the object passed as an argument.

Refer to the below example after the Orders class used above implements Comparable interface and overrides compareTo() method.

package com.coderdesks.basic;

public class Orders implements Comparable<Orders>
{

	private int orderId;
	
	private double amount;
	
	private String orderBy;

	public Orders(){
		
	}

	public Orders(int orderId, double amount, String orderBy) {
		super();
		this.orderId = orderId;
		this.amount = amount;
		this.orderBy = orderBy;
	}

	@Override
	public String toString() {
		return "Orders [orderId=" + orderId + ", amount=" + amount + ", orderBy=" + orderBy + "]";
	}

	@Override
	public int compareTo(Orders o) {
		return (this.orderId < o.orderId) ?-1 :((this.orderId == o.orderId) ? 0 : 1);
	}
}

Once we run the below class it will sort the array of Orders class objects.

package com.coderdesks.basic;

import java.util.Arrays;

public class ComparatorVsComparable {

	public static void main(String[] args) {
		
		System.out.println("Default sorting of orders array");
		Orders [] orders = {
				new Orders(212,2000.40, "Tom"),
				new Orders(132,2999.00, "Sam"),
				new Orders(245,2070.10, "Mark"),
				new Orders(653,2020.33, "Calvin")
		};
		
		Arrays.sort(orders);
		for(Orders order : orders){
			System.out.println(order);
			
		}
	}	
}

Output:

Default sorting of orders array
Orders [orderId=132, amount=2999.0, orderBy=Sam]
Orders [orderId=212, amount=2000.4, orderBy=Tom]
Orders [orderId=245, amount=2070.1, orderBy=Mark]
Orders [orderId=653, amount=2020.33, orderBy=Calvin]

Here you can see the array of Orders is sorted based on the orderId.

So far so good, we have to sort the Orders array by “orderId” and we can do it. But in most of the real-life scenarios, we want sorting based on different parameters. Let’s take an example of the Orders class used above, where the owner may want to sort the orders by their amount, the person managing the reports may want to sort them by order id and someone else wants to sort them by name. In this case, if we use a Comparable interface that provides default sorting and we can’t change it dynamically, we can only sort using one of the fields.

Here Comparator interface comes into the picture. The Comparator interface allows you to provide multiple methods with different ways of sorting. We can choose the way we want to sort the elements.

Comparator:

The java.util.Comparator interface provides compare(Object o1,Object o2) method for sorting. To sort compare method needs to be implemented in such a way that it returns a negative integer if the first object is less than the second one, returns 0 if both are equal, and a positive integer if the first object is greater than the second one.

Let’s modify the Orders class by providing sorting using amount and order by as well. Observe the Orders class with the implementation of the Comparator along with the default sorting.

package com.coderdesks.basic;

import java.util.Comparator;

public class Orders implements Comparable<Orders>
{

	private int orderId;
	
	private double amount;
	
	private String orderBy;

	public Orders(){
		
	}

	public Orders(int orderId, double amount, String orderBy) {
		super();
		this.orderId = orderId;
		this.amount = amount;
		this.orderBy = orderBy;
	}

	@Override
	public String toString() {
		return "Orders [orderId=" + orderId + ", amount=" + amount + ", orderBy=" + orderBy + "]";
	}

	@Override
	public int compareTo(Orders o) {
		return (this.orderId < o.orderId) ?-1 :((this.orderId == o.orderId) ? 0 : 1);
	}
	
	public static Comparator<Orders> sortByAmount = new Comparator<Orders>() {
		
		@Override
		public int compare(Orders o1, Orders o2) {

			return (o1.amount < o2.amount) ? -1 : ( (o1.amount == o2.amount) ? 0 : 1);
		}
	};
	
	public static Comparator<Orders> sortByOrderBy = new Comparator<Orders>() {
		
		@Override
		public int compare(Orders o1, Orders o2) {

			return o1.orderBy.compareTo(o2.orderBy);
		}
	};
}

To check if the changes we made are working or not run the below code snippet.

package com.coderdesks.basic;

import java.util.Arrays;

public class ComparatorVsComparable {

	public static void main(String[] args) {
		
		System.out.println("Default sorting of orders array \n");
		Orders [] orders = {
				new Orders(212,2000.40, "Tom"),
				new Orders(132,2999.00, "Sam"),
				new Orders(245,2070.10, "Mark"),
				new Orders(653,2020.33, "Calvin")
		};
		
		Arrays.sort(orders);
		for(Orders order : orders){
			System.out.println(order);
			
		}
		
		System.out.println(" ");

		System.out.println("Sorting of orders array using amount \n");
		
		Arrays.sort(orders, Orders.sortByAmount);
		
		for(Orders order : orders){
			System.out.println(order);
			
		}
		System.out.println(" ");
		
		System.out.println("Sorting of orders array using order by \n");
		
		Arrays.sort(orders, Orders.sortByOrderBy);
		
		for(Orders order : orders){
			System.out.println(order);
			
		}
	}
}

Output:

Default sorting of orders array 

Orders [orderId=132, amount=2999.0, orderBy=Sam]
Orders [orderId=212, amount=2000.4, orderBy=Tom]
Orders [orderId=245, amount=2070.1, orderBy=Mark]
Orders [orderId=653, amount=2020.33, orderBy=Calvin]
 
Sorting of orders array using the amount 

Orders [orderId=212, amount=2000.4, orderBy=Tom]
Orders [orderId=653, amount=2020.33, orderBy=Calvin]
Orders [orderId=245, amount=2070.1, orderBy=Mark]
Orders [orderId=132, amount=2999.0, orderBy=Sam]
 
Sorting of orders array using order by 

Orders [orderId=653, amount=2020.33, orderBy=Calvin]
Orders [orderId=245, amount=2070.1, orderBy=Mark]
Orders [orderId=132, amount=2999.0, orderBy=Sam]
Orders [orderId=212, amount=2000.4, orderBy=Tom]

We can even provide the Comparator implementation in a separate class. This is the major advantage of the Comparator interface you can use it with third-party classes or the class you aren’t allowed to modify in your code.

Let’s modify our Orders class by adding a date field orderDate and providing the sorting based on orderDate using a separate class. In this example, we will also use Collections.sort() method to sort the list of orders.

After modifying the Orders class it will look as below.

package com.coderdesks.basic;

import java.util.Comparator;
import java.util.Date;

public class Orders implements Comparable<Orders>
{

	private int orderId;
	
	private double amount;
	
	private String orderBy;
	
	private Date orderDate;

	public Orders(){
		
	}

	public Orders(int orderId, double amount, String orderBy, Date orderDate) {
		super();
		this.orderId = orderId;
		this.amount = amount;
		this.orderBy = orderBy;
		this.orderDate = orderDate; 
	}


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

	@Override
	public int compareTo(Orders o) {
		return (this.orderId < o.orderId) ?-1 :((this.orderId == o.orderId) ? 0 : 1);
	}
	
	public static Comparator<Orders> sortByAmount = new Comparator<Orders>() {
		
		@Override
		public int compare(Orders o1, Orders o2) {

			return (o1.amount < o2.amount) ? -1 : ( (o1.amount == o2.amount) ? 0 : 1);
		}
	};
	
	public static Comparator<Orders> sortByOrderBy = new Comparator<Orders>() {
		
		@Override
		public int compare(Orders o1, Orders o2) {

			return o1.orderBy.compareTo(o2.orderBy);
		}
	};

	public int getOrderId() {
		return orderId;
	}

	public double getAmount() {
		return amount;
	}

	public String getOrderBy() {
		return orderBy;
	}

	public Date getOrderDate() {
		return orderDate;
	}	
}

Here is the “OrdersDateComparator” class providing implementation to compare the method of the Comparator interface.

package com.coderdesks.basic;

import java.util.Comparator;

public class OrdersDateComparator implements Comparator<Orders>{

	@Override
	public int compare(Orders o1, Orders o2) {

		return o1.getOrderDate().compareTo(o2.getOrderDate());
	}
}

To test the above changes let run the below code snippet.

package com.coderdesks.basic;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class ComparatorVsComparable {

	public static void main(String[] args) {
		
		Orders [] orders = {
				new Orders(212,2000.40, "Tom",getDateFromString("21-09-2019")),
				new Orders(132,2999.00, "Sam",getDateFromString("12-09-2019")),
				new Orders(245,2070.10, "Mark",getDateFromString("18-08-2019")),
				new Orders(653,2020.33, "Calvin",getDateFromString("01-04-2019"))
		};		
		
		System.out.println("Sorting of orders list using order date \n");
		
		List<Orders> orderList = Arrays.asList(orders);
		
		Collections.sort(orderList,new OrdersDateComparator());

		for(Orders order : orderList){
			System.out.println(order);
			
		}
		
	}

	private static Date getDateFromString(String strDate){
		try {
			return new SimpleDateFormat("dd-MM-yyyy").parse(strDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
}

Output:

Sorting of orders list using order date 

Orders [orderId=653, amount=2020.33, orderBy=Calvin, orderDate=Mon Apr 01 00:00:00 IST 2019]
Orders [orderId=245, amount=2070.1, orderBy=Mark, orderDate=Sun Aug 18 00:00:00 IST 2019]
Orders [orderId=132, amount=2999.0, orderBy=Sam, orderDate=Thu Sep 12 00:00:00 IST 2019]
Orders [orderId=212, amount=2000.4, orderBy=Tom, orderDate=Sat Sep 21 00:00:00 IST 2019]

ComparableComparator
For Comparable Arrays.sort() and Collections.sort() method automatically use compareTo() method. For Comparator client has to provide the implementation of Comparator interface.
java.lang.Comparablejava.util.Comparator
Method compareTo(Object o) takes only one argumentMethod compare(Object o1,Object o2) takes two arguments
Provides single way of sorting also called default way. Provides methods to sort based on different parameters
The class has to implement Comparable interface to enable sortingWe can sort even after implementing Comparator in a separate class. This features allows us to sort third party classes well.

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 !!