Showing posts with label core java. Show all posts
Showing posts with label core java. Show all posts

Core concept of Comparable and Comparator interface in Java | interview question on Java collection

package com.rajeev;


1. By Using comparable interface sorting logic(compareTo(Object obj)) implements within the class
so every time when you want to change sorting logic then there must be change inside the class. suppose
in below code right now sorting logic is based on employee's name when you want to changed it to based on employee Id then you
need to change logic as below

 @Override
       public int compareTo(Object obj) {
              emplyee emp=(emplyee)obj;
             return Integer.toString(this.employeeId).compareTo(Integer.toString(emp.getEmployeeId()));
       }

import java.util.*;
import java.util.Iterator;
import java.util.TreeSet;
class emplyee implements Comparable

{
       String name;
       int employeeId;
       public emplyee(String name, int employeeId )
       {
              this.name=name;
              this.employeeId=employeeId;
       }
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
       public int getEmployeeId() {
              return employeeId;
       }
       public void setEmployeeId(int employeeId) {
              this.employeeId = employeeId;
       }
        public int compareTo(Object obj) {
              emplyee emp=(emplyee)obj;
             return this.name.compareTo(emp.getName());
       }
       /*@Override
       public int compareTo(Object obj) {
              emplyee emp=(emplyee)obj;
             return Integer.toString(this.employeeId).compareTo(Integer.toString(emp.getEmployeeId()));
       }*/
}
public class comparableTest {
       public static void main(String [] args)
       {
              TreeSet ts= new TreeSet();
              ts.add(new emplyee("Humud",800));
              ts.add(new emplyee("rajeev",600));
              ts.add(new emplyee("aalu",100));
              //ts.add("rajeev");
              //ts.add("Aalu");
              Iterator it =ts.iterator();
              while(it.hasNext())
              {
                     emplyee em=(emplyee)it.next();
                     System.out.println("SOrted -------"+em.getName());
              }
       }
}


2. By Using Comparator interface you have to write to your sorting logic outside the
   class . so when you want change the sorting logic not need to change logic inside the emplyee class

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

class nameComparator implements Comparator
{
       @Override
       public int compare(Object obj1, Object obj2) {
              emplyee emp=(emplyee)obj1;
              emplyee emp2=(emplyee)obj2;
              return Integer.toString(emp.employeeId).compareTo(Integer.toString(emp2.getEmployeeId()));
       }
}
class emplyeeIdComparator implements Comparator
{
       @Override
       public int compare(Object obj1, Object obj2) {
              emplyee emp=(emplyee)obj1;
              emplyee emp2=(emplyee)obj2;
              return emp.getName().compareTo(emp2.getName());
       }
}
class emplyee
{
       String name;
       int employeeId;
       public emplyee(String name, int employeeId )
       {
              this.name=name;
              this.employeeId=employeeId;

       }
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
       public int getEmployeeId() {
              return employeeId;
       }
       public void setEmployeeId(int employeeId) {
              this.employeeId = employeeId;
       }
       /*@Override
       public int compareTo(Object obj) {
              emplyee emp=(emplyee)obj;
              return Integer.toString(this.employeeId).compareTo(Integer.toString(emp.getEmployeeId()));
       }*/
}
public class comparableTest {
       public static void main(String [] args)
       {
              TreeSet ts= new TreeSet(new emplyeeIdComparator());
              ts.add(new emplyee("Rumud",800));
              ts.add(new emplyee("rajeev",600));
              ts.add(new emplyee("aalu",100));
              //ts.add("rajeev");
              //ts.add("Aalu");
              Iterator it =ts.iterator();
              while(it.hasNext())
              {
                     emplyee em=(emplyee)it.next();
                     System.out.println("SOrted -------"+em.getName());
              }

       }
}



Thread.State in Java? BLOCKED vs WAITING | What is Thread.State in Java? What's it used for?

Thread.State - This is a static nested class (Read more about nested classes in the article - Nested Classes & Inner Classes in Java >>) of the Thread class. This is one of the additions of Java 5 and this class actually inherits the abstract class Enum which is the common base class of all Java language enumeration types i.e., Thread.State is actually is actually an enumeration type.

Thread.State enumeration contains the possible states of a Java thread in the underlying JVM. These states are different from the Operating System thread states. The possible values of the Thread.State are:-

    NEW - this state represents a new thread which is not yet started.
    RUNNABLE - this state represents a thread which is executing in the underlying JVM. Here executing in JVM doesn't mean that the thread is always executing in the OS as well - it may wait for a resource from the Operating system like the processor while being in this state.
    BLOCKED - this state represents a thread which has been blocked and is waiting for a moniotor to enter/re-enter a synchronized block/method. A thread gets into this state after calling Object.wait method.
    WAITING - this state represnts a thread in the waiting state and this wait is over only when some other thread performs some appropriate action. A thread can get into this state either by calling - Object.wait (without timeout), Thread.join (without timeout), or LockSupport.park methods.
    TIMED_WAITING - this state represents a thread which is required to wait at max for a specified time limit. A thread can get into this state by calling either of these methods: Thread.sleep, Object.wait (with timeout specified), Thread.join (with timeout specified), LockSupport.parkNanos, LockSupport.parkUntil
    TERMINATED - this state reprents a thread which has completed its execution either by returning from the run() method after completing the execution OR by throwing an exception which propagated from the run() method and hence caused the termination of the thread.

Difference between BLOCKED state and WAITING / TIMED_WAITING states?


When a thread calls Object.wait method, it releases all the acquired monitors and is put into WAITING (or TIMED_WAITING if we call the timeout versions of the wait method) state. Now when the thread is notified either by notify() or by notifyAll() call on the same object then the waiting state of the thread ends and the thread starts attempting to regain all the monitors which it had acquired at the time of wait call. At one time there may be several threads trying to regain (or maybe gain for the first time) their monitors. If more than one threads attempt to acquire the monitor of a particular object then only one thread (selected by the JVM scheduler) is granted the monitor and all other threads are put into BLOCKED state. Got the difference?

Difference between WAITING and TIMED_WAITING states?

The difference is quite obvious between the two. A thread in a TIMED_WAITING state will wait at max for the specified timeout period whereas a thread in the WAITING state keeps waiting for an indefinite period of time. For example, if a thread has called Object.wait method to put itself into WAITING state then it'll keep waiting until the thread is interrupted either by notify() method (OR by notifyAll() method) call on the same object by another thread. Similarly, if a thread has put itself into WAITING state by calling Thread.join method then it'll keep waiting until the specified thread terminates.

We can easily figure out that a thread in a WAITING state will always be dependent on an action performed by some other thread whereas a thread in TIMED_WAITING is not completely dependent on an action performed by some other thread as in this case the wait ends automatically after the completion of the timeout period.

Java : Static Initialization Blocks and their alternatives in Java | what is initialization blocks in java

The easiest way of initializing fields (static or instance) in Java at the time of their declaration is simply by providing a compile time constant value of a compatible data type. For example:


public class InitializationWithConstants{

public static int staticIntField = 100;
private boolean instanceBoolField = true;

}


This type of initialization has its limitation due to its simplicity and it can not support initialization based even on some moderately complex logic - like initializing only selected elements of a complex array using some logic in a for loop.

Here comes the need for static initialization blocks and initializer blocks for initializing static and instance fields, respectively.

Static Initialization Blocks - what are they and how to use them?

It's a normal block of code enclosed within a pair of braces and preceded by a 'static' keyword. These blocks can be anywhere in the class definition where we can have a field or a method. The Java runtime guarantees that all the static initialization blocks are called in the order in which they appear in the source code and this happens while loading of the class in the memory.


public class InitializationWithStaticInitBlock{

public static int staticIntField;
private boolean instanceBoolField = true;

static{
 //compute the value of an int variable 'x'
 staticIntField = x;
}
}


Since static initialization blocks are actually code-blocks so they will allow us to initialize even those static fields which require some logical processing to be done for them to get their initial values.

Alternative to Static Initialization Blocks

A private static method is a suitable alternative to the static initialization blocks. In fact it has some advantages over static initialization blocks as well like you can re-use a private static method to re-initialize a static field in case you need it. So, you kind of get more flexibility with a private static method in comparison to the corresponding static initialization block. This should not mislead that a 'public' static method can't do the same. But, we are talking about a way of initializing a class variable and there is hardly any reason to make such a method 'public'. More about how to pick the access control modifiers here - Choosing a suitable access control modifier >>


public class InitializationWithPrivateStaticMethod{

public static int staticIntField = privStatMeth();
private boolean instanceBoolField = true;

private static int privStatMeth() {
 //compute the value of an int variable 'x'
 return x;
}
}

How to create Proxy object in java | creation of proxy object concept in spring AOP

J2SE v1.3 has introduced a dynamic proxy class in the Java Reflection package.
A dynamic proxy class implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface.
 Proxy classes and instances are created using static methods of the java.lang.reflect.Proxy class.Each proxy class has one public constructor that takes one argument, an implementation of the java.lang.reflect.InvocationHandler interface.


package com.prox;

public interface Showable {
   
public void show();
}





-------------------------------------


package com.prox;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyHandler implements InvocationHandler{
   
    Showable target;
    public  MyHandler(Showable target)
    {
        this.target=target;
    }
    public Object invoke(Object proxy, Method m, Object [] args)throws Throwable
    {
        Object o= m.invoke(target, args);
        return o;
    }

}


------------------------------------------

package com.prox;

public class A implements Showable{
   
    public void show()
    {
       
        System.out.println("Inside the Class A");
    }

}


---------------------------------------------


package com.prox;


import java.lang.reflect.Proxy;

public class ProxyTest {
   
    public static void main(String [] args)
    {
       
        System.out.println("Inside the main method");
        A  target = new  A();
        B  target1 = new  B();
        MyHandler handler= new MyHandler(target1);
        try {
         System.out.println("creating Proxy object");
         Showable pr=(Showable)Proxy.newProxyInstance(B.class.getClassLoader(),new
                Class[]{Showable.class}, handler);
       
        System.out.println("The Invoking show method on proxy object");
        pr.show();
        System.out.println("the proxy object"+pr.getClass().getName());
        //B b=(B)pr;
        //b.notShow();
        }
       
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }

}


-------------------------------------------

In above code we have created a proxy object concept

Drawback of proxy object

  • One limitation is that the method must be called through an instance of the proxy class. So nested methods calls, for instance, would not be intercepted.
  • Another limitation is that the method must have been defined in an Interface that is implemented by the object being proxied. It can not be called through an instance of a class that does not implement an interface.