Tuesday, 10 December 2019

ConcurrentLinkedDeque in Java

ConcurrentLinkedDeque is another concurrent collection which is part of the java.util.concurrent package. Unlike many other concurrent collections like ConcurrentHashMap, CopyOnWriteArrayList which were added in Java 5 ConcurrentLinkedDeque was added in Java 7.

ConcurrentLinkedDeque in Java is an unbounded thread-safe Deque which stores its elements as linked nodes. Since it implements deque interface ConcurrentLinkedDeque supports element insertion and removal at both ends. You will find methods like addFirst(), addLast(), getFirst(), getLast(), removeFirst(), removeLast() to facilitate operations at both ends.

Like most other concurrent collection implementations, this class does not permit the use of null elements.

Usage of ConcurrentLinkedDeque

A ConcurrentLinkedDeque in Java is an appropriate choice when many threads share access to a common collection as concurrent insertion, removal, and access operations execute safely across multiple threads.

Note that it doesn't block operations as done in the implementation of BlockingDequeue interface like LinkedBlockingDeque. So there are no putFirst(), takeFirst() or putLast(), takeLast() methods which will wait if required.

Java ConcurrentLinkedDeque Iterator

ConcurrentLinkedDeque's iterator is weakly consistent, returning elements reflecting the state of the queue at some point at or since the creation of the iterator. Iterators in ConcurrentLinkedDeque do not throw ConcurrentModificationException, and may proceed concurrently with other operations. Elements contained in the queue since the creation of the iterator will be returned exactly once.

ConcurrentLinkedDeque Java Example

Let's create a producer consumer using ConcurrentLinkedDeque. In this code there will be one producer thread putting element into the queue and two consumer threads retrieving elements from the queue. Note that producer thread will put 5 elements.

import java.util.Deque;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ConcurrentLDeQDemo {

    public static void main(String[] args) {
        //Buffer buffer = new Buffer();
        Deque<Integer> clDQue = new ConcurrentLinkedDeque<Integer>();
        ExecutorService executor = Executors.newFixedThreadPool(3);
        // Calling one producer
        executor.execute(new ProdTask(clDQue));
        // Calling two consumers
        executor.execute(new ConTask(clDQue));
        executor.execute(new ConTask(clDQue));
        executor.shutdown();
    }
}

/**
 * 
 */
class ProdTask implements Runnable{
    // Shared Deque object
    Deque<Integer> clDQue;
    ProdTask(Deque<Integer> clDQue){
        this.clDQue = clDQue;
    }
    @Override
    public void run() {
        for(int i = 0; i < 5; i++){
            clDQue.add(i);
        }
    }
}

/**
 * 
 */
class ConTask implements Runnable{
    Integer value;
    // Shared Deque object
    Deque<Integer> clDQue;
    ConTask(Deque<Integer> clDQue){
        this.clDQue = clDQue;
    }
    @Override
    public void run() {
         while ((value = clDQue.pollFirst()) != null) {
             if(value == null){
                 System.out.println("No value to poll");
             }else{
                 System.out.println("Consumer recd - " + value);
             }
         }
    }    
}

Output

Consumer recd - 0
Consumer recd - 1
Consumer recd - 2
Consumer recd - 3
Consumer recd - 4

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


Related Topics

  1. ConcurrentLinkedQueue in Java
  2. BlockingQueue in Java Concurrency
  3. BlockingDeque in Java Concurrency
  4. ConcurrentHashMap in Java
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. Race condition in Java multi-threading
  2. Lambda expressions in Java 8
  3. Functional interface annotation in Java 8
  4. interface static methods in Java 8
  5. How HashMap internally works in Java
  6. fail-fast Vs fail-safe iterator in Java
  7. Multi catch statement in Java 7
  8. Print odd-even numbers using threads and wait-notify

Monday, 9 December 2019

DelayQueue in Java Concurrency

DelayQueue in Java is an implementation of BlockingQueue interface and is added in Java 5 along with other concurrent utilities like CyclicBarrier, Exchanger, ConcurentSkipListMap, CopyOnWriteArraySet etc.

DelayQueue in Java is an unbounded implementation of BlockingQueue, that's where it is different from the other implementations of BlockingQueue like ArrayBlockingQueue (Always bounded) and LinkedBlockingQueue (both bounded and unbounded options). Though it is similar to PriorityBlockingQueue in this behaviour as PriorityBlockingQueue is also unbounded.

DelayQueue stores Delayed elements

DelayQueue in Java is a special implementation of BlockingQueue as it can only store elements of type Delayed and an element can only be retrieved from DelayQueue when its delay has expired.

Delayed interface which defines the type for the elements in the DelayQueue has one method

  • getDelay(TimeUnit unit) - Returns the remaining delay associated with this object, in the given time unit.

Delayed interface also extends Comparable interface so compareTo(T o) method should also be implemented. This method implementation will decide whether you want to retrieve elements in ascending order of delay or descending.

According to JavaDocs "An implementation of this interface must define a compareTo method that provides an ordering consistent with its getDelay method."

So, just to sum it up; DelayQueue stores elements of type Delayed. When you implement Delayed interface two methods have to be implemented getDelay(TimeUnit unit) and compareTo(T o).

Ordering in Java DelayQueue

DelayQueue orders its elements (of type Delayed) based on the remaining delay associated with the element as returned by the getDelay() method. The head of the queue is the Delayed element whose delay expired furthest in the past where as the tail of the queue is the Delayed element with the longest remaining delay expiration time.

Producer Consumer Java example using DelayQueue

Let's create a producer consumer using the DelayQueue. There is also a class DelayClass which implements Delayed interface and implements the required methods- getDelay() and compareTo(). DelayQueue will store objects of DelayClass.

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayQDemo {

    public static void main(String[] args) {
        // delay of 2 seconds
        final long delay = 2000;
        BlockingQueue<DelayClass> delayQ = new DelayQueue<DelayClass>();
        
        // Producer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < 5; i++){
                    try {
                        // putting elements in delay queue
                        delayQ.put(new DelayClass("item"+i, delay));
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        System.out.println("Error while putting values in the Queue "
                         + e.getMessage());
                    }
                }
            }
        }.start();
        
        // Consumer thread
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < 5; i++){
                    try {
                        // retrieving elements from delay queue
                        System.out.println(" Consumer got - " + delayQ.take());
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        System.out.println("Error while retrieving value from the Queue "
                         + e.getMessage());
                    }
                }
            }
        }.start();
    }

}

// Delayed interface implementing class
class DelayClass implements Delayed{
    private String item;
    private long expireTime;
    DelayClass(String item, long delay){
        this.item = item;
        // Expiretime is currenttime+delay, so if delay of 2 sec is required
        // expiration from queue will hppn after
        // currenttime + 2 sec
        this.expireTime = System.currentTimeMillis() + delay;
    }
    
    @Override
    public long getDelay(TimeUnit unit) {
        long diff = expireTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }
    
    @Override
    public int compareTo(Delayed o) {
        if(this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)){
            return -1;
        }
        if(this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)){
            return 1;
        }
        return 0;
            
    }
    
    public String toString(){
        return "item = " + item + " expireTime = " + expireTime;
    } 
}

Output

Consumer got - item = item0 expireTime = 1458998017469
Consumer got - item = item1 expireTime = 1458998017531
Consumer got - item = item2 expireTime = 1458998017594
Consumer got - item = item3 expireTime = 1458998017656
Consumer got - item = item4 expireTime = 1458998017719

Here it can be seen elements are retrieved from the queue only after the delay expires.

Points to remember

  1. DelayQueue in Java stores element of type Delayed.
  2. Element is retrieved from DelayQueue only when its delay has expired.
  3. The head of the queue is thatDelayed element whose delay expired furthest in the past.
  4. If no delay has expired there is no head and poll will return null.
  5. Expiration occurs when an element's getDelay(TimeUnit tu) method returns a value less than or equal to zero.

Reference: https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/concurrent/DelayQueue.html

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


Related Topics

  1. SynchronousQueue in Java
  2. BlockingDeque in Java Concurrency
  3. LinkedTransferQueue in Java
  4. ReentrantReadWriteLock in Java
  5. Semaphore in Java Concurrency

You may also like-

  1. ConcurrentHashMap in Java
  2. Deadlock in Java multi-threading
  3. Synchronization in Java multithreading
  4. Java Collections Interview Questions
  5. Lambda expression and variable scope
  6. Autowiring using annotations in Spring
  7. try-with-resources in Java 7
  8. How to Find The Longest Palindrome in The Given String

Bubble Sort Program in Python

In this post we’ll see how to write Bubble sort program in Python. Bubble sort is considered the simplest sorting algorithm out of the three simpler sorting algorithms bubble sort, insertion sort and selection sort. Bubble sort is considered the slowest too because of a proportionally large number of swaps along with the comparisons.

How does Bubble sort work

In Bubble sort adjacent elements are compared and swapped if element at left is greater than element at right. For example if n[0] and n[1] are compared and n[0] > n[1] then n[0] and n[1] are swapped. Then you move by one index and compare the adjacent elements i.e. n[1] and n[2].

By the end of first pass you should have the maximum element in the list at the rightmost position. Since the maximum element bubbles up to the top thus the name Bubble sort.

To sum up the steps for bubble sort-

  1. Compare the adjacent elements.
  2. If element at the left is greater than the element at the right then swap the elements.
  3. Move one position right. Start from point 1.

In the next pass again you start from the two leftmost elements and compare the elements and swap if required. Since the rightmost element is already in its sorted position so this pass runs till (N-1) elements.

For example if you have an array [5, 3, 8, 2] then in the first pass-

Iteration 1- Initially 5 is compared with 3, since 5 (element at left) is greater than 3 (element at right), elements are swapped making the array [3, 5, 8, 2].

Iteration 2- Move to next position and compare element at index 1 and index 2 (5 and 8), since 5 is not greater than 8 so swapping is not done and array remains [3, 5, 8, 2].

Iteration 3- Again move over one position and compare 8 and 2. Since 8 is greater than 2, elements are swapped giving us the array as [3, 5, 2, 8].

As you can see by the end of first pass the maximum element is at the rightmost position. In the next pass last element is not included in the comparison as it is already at its final position so the array that is considered for comparison and swapping effectively becomes [3, 5, 2].

Bubble Sort Python program

def bubble_sort(nlist):
    list_length = len(nlist)
    # reduce length by 1 in each pass
    for i in range(list_length-1, 0, -1):
        for j in range(i):
            # compare
            if nlist[j] > nlist[j+1]:
                # swap elements
                nlist[j+1], nlist[j] = nlist[j], nlist[j+1]


nlist = [47, 85, 62, 34, 7, 10, 92, 106, 2, 54]
print('Original List-', nlist)
bubble_sort(nlist)
print('Sorted List-', nlist)

Output

Original List- [47, 85, 62, 34, 7, 10, 92, 106, 2, 54]
Sorted List- [2, 7, 10, 34, 47, 54, 62, 85, 92, 106]

Time and Space complexity of Bubble sort

In Bubble sort (N-1) comparisons are required in the first pass, (N-2) comparisons in the second pass, (N-3) comparisons in the third pass and so on.

So the total number of comparisons is- N(N-1)/2

Thus the time complexity of Bubble sort is O(n2).

Bubble sort is an in-place sorting algorithm and doesn’t require any auxiliary space so the space complexity of Bubble sort is O(1).

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

>>>Return to Python Programs Page


Related Topics

  1. Python Program to Check Armstrong Number
  2. Python Program to Check if Strings Anagram or Not
  3. Python break Statement With Examples
  4. List in Python With Examples
  5. String Slicing in Python

You may also like-

  1. User-defined Exceptions in Python
  2. Functions in Python
  3. Local, Nonlocal And Global Variables in Python
  4. Python count() method - Counting Substrings
  5. Difference Between HashMap And Hashtable in Java
  6. Binary Search Program in Java
  7. String Pool in Java
  8. Spring Boot Spring Initializr

Saturday, 7 December 2019

Difference Between Checked And Unchecked Exceptions in Java

Before going into the differences between checked and unchecked exceptions in Java let's first see what these two types of exceptions are.


Checked Exception in Java

As we know from the exception hierarchy, Throwable is the parent class of all the Exception types. Immediately below Throwable there is a subclass called Exception. This Exception class has one subclass called RunTimeException.

difference between checked and unchecked exception in Java

If an exception is a subclass of Exception but does not inherit from RuntimeException, it is a checked exception. The restriction with a checked exception is that it needs to be either caught in a method (with in a try-catch block), or the method needs to specify that exception in a throws clause declaration.

Checked exception classes in Java

  • IOException
  • FileNotFoundException
  • ParseException
  • ClassNotFoundException
  • CloneNotSupportedException
  • InstantiationException
  • InterruptedException
  • NoSuchMethodException
  • NoSuchFieldException

Unchecked Exception in Java

With in the exception hierarchy if an exception is a subclass of RuntimeException, it is an unchecked exception. An unchecked exception can also be caught by wrapping the code in try-catch block, but it does not have to as it is not verified at compile time. Thus the name 'unchecked'.

Most of the times these exceptions occur due to the programming errors. Unchecked exceptions can be thought of arising due to not having a proper testability condition with in a program. Take 3 examples.

  • NullPointerException - If already tested for null using if condition it won't arise.
  • ArrayIndexOutOfBoundsException - If already tested for length of an array it won't arise.
  • ClassCastException - if already checked using instanceof operator it won't arise.

Java's unchecked exceptions

  • ArrayIndexOutOfBoundsException
  • ClassCastException
  • IllegalArgumentException
  • IllegalStateException
  • NullPointerException
  • NumberFormatException
  • AssertionError
  • ExceptionInInitializerError
  • StackOverflowError
  • NoClassDefFoundError

Checked Vs Unchecked exception in Java

Now when we know what are checked and unchecked exceptions, it is easy to list out the differences between checked and unchecked exceptions in Java.

  • Checked Exception is a direct subclass of Exception where as unchecked exception is a subclass of RunTimeException.
  • Checked exception should be wrapped in a try-catch block or specified as throws clause where as there is no such requirement for unchecked exception.
  • Failure to provide exception handling mechanism for checked exception result in compiler error whereas no compile time error for unchecked exception.
  • Checked exceptions are designed to reduce the number of exceptions which are not properly handled and where there is a reasonable chance for recovery. UnCheckedExceptions are mostly programming errors.

Usage of checked exception in Java

There is a lot of debate over whether checked exceptions are at all needed or not. General complain is that having checked exceptions result in a lot of boiler plate code. That problem has been recognized and Java7 has a feature called multi-catch statement to reduce exception handling code.

For checked exceptions Java language Specification says; "This compile-time checking for the presence of exception handlers is designed to reduce the number of exceptions which are not properly handled".

Checked Exceptions should be used to declare expected errors from which there are chances to recover from. It doesn't make sense telling callers to anticipate exceptions that they cannot recover from.

As example If a user attempts to read from a non-existing file, the caller can prompt him for a new filename. On the other hand, if the method fails due to a programming bug (invalid input parameters or incorrect method implementation) there is nothing the application can do to fix the problem in mid-execution. The best it can do is log the problem and wait for the developer to fix it at a later time.

Why unchecked exception

According to the Java Language Specification "run-time exception classes are exempted because, in the judgment of the designers of the Java programming language, having to declare such exceptions would not aid significantly in establishing the correctness of programs. Many of the operations and constructs of the Java programming language can result in exceptions at run time. The information available to a Java compiler, and the level of analysis a compiler performs, are usually not sufficient to establish that such run-time exceptions cannot occur, even though this may be obvious to the programmer. Requiring such exception classes to be declared would simply be an irritation to programmers."

Proper usage of Unchecked Exception

One of the best practices for the exception handling is to preserve loose coupling. According to that an implementation specific checked exception should not propagate to another layer. As Exp. SQL exception from the DataAccessCode (DAO layer) should not propagate to the service (Business) layer. The general practice in that case is to convert database specific SQLException into an unchecked exception and throw it.

catch(SQLException ex){
    throw new RuntimeException("DB error", ex);

Points to note -

  • Checked exception classes are direct descendant of Exception class.
  • Unchecked exception classes are direct descendant of RunTimeException class, where RunTimeException class is the sub class of Exception class.
  • Checked exception must be handled either using try-catch block or declared using throws, not doing that will result in compile time error.
  • Not handling unchecked exception does not result in compile time error.
  • RunTime and Checked exceptions are functionally equivalent, whatever handling or recovery checked exceptions can do, runtime exceptions can also do. For checked exceptions it has been made sure (forced) that handling is there by making it a compile time error.

That's all for this topic Difference Between Checked And Unchecked Exceptions in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. final Vs finally Vs finalize in Java
  2. Try-With-Resources in Java Exception Handling
  3. Nested Try Statements in Java Exception Handling
  4. Best Practices For Exception Handling in Java
  5. Java Exception Handling Interview Questions

You may also like-

  1. static import in Java
  2. Method overloading in Java
  3. varargs in Java
  4. How HashMap internally works in Java
  5. Overriding hashCode() and equals() method in Java
  6. Race condition in Java multi-threading
  7. How to create PDF from XML using Apache FOP
  8. Lambda expression and variable scope

Friday, 6 December 2019

How to Create Your Own BlockingQueue - Java Program

This post shows how you can create your own BlockingQueue in Java using ReentrantLock and Condition interface. Condition interface provides method await and signal which work the same way as wait and notify.

Example code

Here we have a class called BufferClass which has an array of type Object, whose length is 5. So, 5 is the bound for buffer, if 5 values are already added to the array it will be blocked until at least one value is retrieved from the array.

put() and take() method are used to add value to an array and retrieve value from an array respectively.

BufferClass

 
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BufferClass {
 final Lock lock = new ReentrantLock();
 // Conditions
 final Condition produce  = lock.newCondition(); 
 final Condition consume = lock.newCondition(); 

 final Object[] valueArr = new Object[5];
 int putIndex, takeIndex;
 int count;

 public void put(Object x) throws InterruptedException {
  //System.out.println("count -- " + count);
  //System.out.println("Array length -- " + valueArr.length);
  lock.lock();
  try {
    while (count == valueArr.length){
    
    produce.await();
    //System.out.println("Awaiting");
  }
   
   valueArr[putIndex] = x;
   System.out.println("Adding - " + x);
   if (++putIndex == valueArr.length){
        putIndex = 0;
   }
   // increment count
   ++count;
   consume.signal();
  } finally {
      lock.unlock();
  }
 }

    public Object take() throws InterruptedException {
      lock.lock();
      try {
        while (count == 0){
          consume.await();
        }
        Object x = valueArr[takeIndex];
        System.out.println("Retrieving - " + x);
        if (++takeIndex == valueArr.length){
          takeIndex = 0;
        }
        // reduce the count
        --count;
        // signal producer
        produce.signal();
        return x;
      } finally {
        lock.unlock();
      }
    }
}

To test this BufferClass we have another class BufferClassDemo where two threads are created, one will add values to the buffer and another will retrieve values from the buffer. Here 10 values are added, BufferClass should ensure if 5 values are already added any attempt to add any further value should be blocked. Same way if the buffer is empty any attempt to retrieve value should be blocked.

 
public class BufferClassDemo {
 
 public static void main(String[] args) {
  BufferClass bufferClass = new BufferClass();
  // Creating two threads
  Thread producer = new Thread(new Producer(bufferClass));
  Thread consumer = new Thread(new Consumer(bufferClass)); 
  // starting threads
  producer.start();
  consumer.start();
 }
}

class Producer implements Runnable {

    private BufferClass bufferClass;
    
    public Producer(BufferClass bufferClass){
        this.bufferClass = bufferClass;
    }
    @Override
    public void run() {
      for (int i = 1; i <= 10; i++) {
            try {
                //Thread.sleep(10);                            
             bufferClass.put(i);                            
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consumer implements Runnable {
 private BufferClass bufferClass;
    
    public Consumer(BufferClass bufferClass){
        this.bufferClass = bufferClass;
    }
    @Override
    public void run() {
      for (int i = 1; i <= 10; i++) {
            try {
               // Thread.sleep(500);
             bufferClass.take();               
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

Output

Output from one of the run. Note that output may vary but the condition of not having more than 5 elements and blocking any attempt to add should hold.

Adding - 1
Adding - 2
Adding - 3
Adding - 4
Adding - 5
Retrieving - 1
Retrieving - 2
Retrieving - 3
Retrieving - 4
Retrieving - 5
Adding - 6
Adding - 7
Adding - 8
Retrieving - 6
Retrieving - 7
Retrieving - 8
Adding - 9
Retrieving - 9
Adding - 10
Retrieving - 10

That's all for this topic How to Create Your Own BlockingQueue - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. ArrayBlockingQueue in Java Concurrency
  2. How to run threads in sequence - Java Program
  3. How to create deadlock in Java multi-threading - Java Program
  4. Print odd-even numbers using threads and wait-notify
  5. Producer-Consumer Java program using ArrayBlockingQueue

You may also like-

  1. Converting string to bytearray - Java Program
  2. How to remove elements from an array - Java Program
  3. How to convert date and time between different time-zones in Java
  4. Callable and Future in Java concurrency
  5. Volatile in Java
  6. PermGen Space Removal in Java 8
  7. Spliterator in Java
  8. Multi catch statement in Java 7

Thursday, 5 December 2019

Generic Class, Interface And Generic Method in Java

In the post generics in Java basics of Java generics are already covered. In this post we’ll see how to create generic class, generic method and generic interface in Java.

Generic class in Java

A generic class is defined with the following format:

class name<T1, T2, ..., Tn> { 
    /* ... */ 
} 

The type parameter section, delimited by angle brackets (<>), follows the class name. It specifies the type parameters (also called type variables) T1, T2, ..., and Tn.

Java Generic class example

Let us create a generic class with two type parameters and see it in use with different data types.

class GenClass<K, V>{
    private K key;
    private V value;
    public GenClass(K key, V value) {
        this.key = key;
        this.value = value;
    }
    public K getKey(){
        return key;
    }
    public V getValue(){
        return value;
    }
}

public class GClassDemo {

    public static void main(String[] args) {
        GenClass<String, String> g1 = new GenClass<>("A", "Value A");
        System.out.println("Key- " + g1.getKey());
        System.out.println("Value- " + g1.getValue());
        
        GenClass<Integer, String> g2 = new GenClass<>(1, "Value 1");
        System.out.println("Key- " + g2.getKey());
        System.out.println("Value- " + g2.getValue());

    }

}

Output

Key- A
Value- Value A
Key- 1
Value- Value 1

Here you can see that first time String is passed as the type for both generic types K and V, where as it is passed as Integer and String second time.

Generic Interface in Java

You can create a generic interface much the same way as a generic class but there are some conditions while implementing the generic interface.

Java Generic interface example

public interface GInterface<E> {
    void setValue(E e);
    E getValue();
}

Class implementing Generic interface

import org.netjs.examples.interfaces.GInterface;

public class GClassImpl<E> implements GInterface<E> {
    E e;
    @Override
    public void setValue(E e) {
        this.e = e;   
    }

    @Override
    public E getValue() {
        return e;
    }
}

Points to note here

  1. Here note that a class that implements a generic interface has to be a generic class.
    public class GClassImpl<E> implements Ginterface<E>
    

    If implementing class of the generic interface is not a generic class that will result in compile time error because the type parameter E is not known in that case.

    public class GClassImpl implements Ginterface<E>
    
    This will result in compile-time error.
  2. Of course providing a proper data type with the interface while implementing it is OK, in that case normal class can be used.
    public class GClassImpl implements GInterface<String> {
        String str;
        @Override
        public void setValue(String e) {
            this.str = e;  
        }
    
        @Override
        public String getValue() {
            return str;
        }
    }
    
    Here you have used String as a type parameter with the interface so it is OK to use a normal class but type will become String in the class then.
  3. A generic class implementing a generic interface can have other parameters too. This is perfectly ok -
    public class GClassImpl<E, K> implements Ginterface<E>
    

Generic method in Java

Any method in the generic class can use the type parameter of the class so that way methods in a generic class are generic.
Generic methods can add more parameters of their own.
There can be generic methods even in a non-generic class.

When you are writing a generic method after the access modifier you need to declare the type parameters then the return type. As example if you are writing a public method that uses one type parameter and doesn’t return anything then it will be written as -
 
public <T> void MethodName(T obj1){

} 

Java Generics - generic method example

If you want to write a generic method that can be used to display elements of an array of any type.

 
public class GenericMethodDemo {  
    public static void main(String[] args) {
        GenericMethodDemo gm = new GenericMethodDemo();
        Integer[] intArray = {1, 2, 3, 4, 5, 6, 7};
        Double[] doubleArray = {3.4, 5.6, 7.8, 1.2, 4.5};
        // integer array
        gm.printElements(intArray);
        // double array
        gm.printElements(doubleArray);
    }
    
    public <T> void printElements(T[] arr){
        // Displaying elements
        for(int i = 0; i < arr.length; i++){
            System.out.print(" " + arr[i]);
        }
        System.out.println();
    }
}

Output

 
1 2 3 4 5 6 7
3.4 5.6 7.8 1.2 4.5

When you are calling a generic method there is no need to specify type (though you can do it if you want). Type will be inferred automatically based on the type of the method arguments. So calling your method using this form gm.<Integer>printElements(intArray); for Integer argument is also ok but it is not needed at all.

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

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Bounded Type Parameter in Java Generics
  2. Wildcard in Java Generics
  3. Type Erasure in Java Generics
  4. AutoBoxing And UnBoxing in Java
  5. Varargs in Java

You may also like-

  1. Interface Default Methods in Java 8
  2. String join() method in Java 8
  3. Spliterator in Java
  4. Difference between HashMap and ConcurrentHashMap in Java
  5. Lock Striping in Java Concurrency
  6. finalize method in Java
  7. static import in Java
  8. try-with-resources in Java 7

Wednesday, 4 December 2019

Difference Between equals() Method And equality Operator == in Java

Difference between equals() method and equality operator “==” in Java is a frequently asked interview question. At the same time it may be a bit confusing for the first-time Java programmer to get the subtle differences between equals and “==”.

So in this post let’s try to find the exact differences between the equals() method and equality operator “==” and where does it make sense to use what.

Java equality operator “==”

equality operator “==” in Java can be used to compare primitive values as well as objects. Though it works just fine with primitive values but in case of objects “==” will compare the references of the objects not the content of the objects.

equals() method in Java

If you want to compare the actual contents of the objects then you will have to override equals method, which is present in Object class so available to all the other classes. Default implementation of equals() in the Object class compares using == operator, so default implementation will compare references.

You will have to override equals method in order to compare your custom class objects.

Difference between equals and “==” in Java

Based on what we have seen so far we can surely list some difference between equals and equality operator “==”.

  1. “==” is an operator where as equals is a method.
  2. “==” can be used with primitive values as well as with objects. Equals method can only be used with objects.
  3. When “==” is used for comparing objects it will compare their references not the actual content. Equals method can compare the actual content of the object but you will have to provide your own implementation for determining the equality of two objects.

Java example using “==” operator and equals()

Let’s move on to see some hands-on code to test the theory stated so far.

public class EqualsMethodDemo {

 public static void main(String[] args) {
    String str1 = new String("Test");
    String str2 = new String("Test");
    
    System.out.println(str1 + " == " + str2 + " - " + (str1 == str2));
    
    System.out.println(str1 + ".equals(" + str2 + ") - " + str1.equals(str2));
 }
}

Output

Test == Test - false
Test.equals(Test) - true

Here two string objects, having the same content, are created. Now comparison of these two strings is done using equality “==” operator and .equals() method.

It can be seen that “==” returns false even though the content of both the string is same. That is because references of both the strings are different. Where as comparison using .equals() returns true.

Here note that String class as well as wrapper classes like Integer, Long provide implementation of equals method which compares the content. Same way for your own classes you will have to provide your own implementation of equals method.

Integer class equals method example

As mentioned above Integer class provides implementation of equals method so that too will compare the content when equal method is used.

public class EqualsMethodDemo {

 public static void main(String[] args) {
  Integer num1 = new Integer(7);
  
  Integer num2 = new Integer(7);
  
  System.out.println(num1 + " == " + num2 + " - " + (num1 == num2));
  
  System.out.println(num1 + " == " + num2 + " - " + num1.equals(num2));
 }
}

Output

7 == 7 - false
7 == 7 - true

That's all for this topic Difference Between equals() Method And equality Operator == in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related Topics

  1. Equality and Relational Operators in Java
  2. Conditional Operators in Java
  3. Ternary Operator in Java
  4. String comparison in Java
  5. Overriding hashCode() and equals() method in Java

You may also like-

  1. Java pass by value or pass by reference
  2. Access modifiers in Java
  3. How HashMap internally works in Java
  4. Fail-Fast Vs Fail-Safe Iterator in Java
  5. Nested Try Statements in Java Exception Handling
  6. Marker interface in Java
  7. Java Multi-Threading Interview Questions
  8. Lambda expressions in Java 8