Monday, December 1, 2014

switch vs if-else

Well, this one has been talked about a millions of times in different forums over the internet, many books also deals with this information as well. With a basic Google search capability you can get a tons of results. But for you, I would love tell you the same story over and over again...

Questions come as follows:
If-else are good in programming, they can deal with logic as expected, then what is the need of having switch-case ?
Both deal with logic and the output of the both are also same but the ways they work are different.
If-else is simply a sequential way of checking every block where switch maintains a hashtable( some call it as jump table ) with different known input/output mapping.
So, this way the switch statements are way faster than If-else ladder in case of larger number of If-else blocks. It is quite obvious and best suited to use switch statements if your code is having more than 6 If-else construct. 6 is not a magic number here. It basically an average result.

Why it is faster ?
In case of If-else the logic is tested for each block until it comes to an equality. On the other hand, switch-case creates a table with known input/output at compile time.
Thus the complexity of switch-case is O(1) while in case of If-else it is a factor of O(n).
The best case for an If-else is if it encounters the first logic block to be true while the worst case is if it encounters the last logic block to be true.
Well there is some overhead to create the hashtable in compile time, which causes some delay. So, 6 is the number you can follow as mentioned earlier.
The next thing you can think is the way switch-case and if-else is written in the code.
if-else is for boolean expressions where switch-case is for integral numbers, characters, enums and String (Java 7 feature).

So, if you are dealing with anything other than switch-case support, you are bound to do the same in if-else.


Where to use what ?
As mentioned, 6 is the number you can consider and keep in mind the switch-case support.
Another check you should do is the way your code needs decision making. For a hint, null check is a point you can consider if-else. Cause, switch-case misses this area.

Palash Kanti Kundu Palash Kanti Kundu Palash Kanti Kundu Palash Kanti Kundu Palash Kanti Kundu Palash Kanti Kundu Palash Kanti Kundu Palash Kanti Kundu Palash Ka Palash Kanti Kundunti Kundu

Deadly Diamond of Death...

Its unpredictable for me to choose...

Suppose we have four classes, ClassA. ClassB, ClassC, ClassD. ClassA is abstract and has an abstract method doGood(); ClassB and ClassC extends ClassA. So they must override doGood();
now comes ClassD in picture which extends both ClassB and ClassC. Now, it does not have to override doGood() cause it s already overridden by parent classes. Again ClassD has another method doEvil() which invokes doGood(). Which doGood() version will it invoke, ClassB version or ClassC version ?

Suppose Java supports multiple inheritance through classes, find the output of the following program


 abstract class A {  
      static int counter = 0;  
      public abstract void doGood();  
      public abstract void changeCounter(int value);  
 }  
 class B extends A {  
      @Override  
      public void doGood() {  
           changeCounter(5);  
      }  
      @Override  
      public void changeCounter(int value) {  
           counter = value;  
      }  
 }  
 class C extends A {  
      @Override  
      public void doGood() {  
           changeCounter(15);  
      }  
      @Override  
      public void changeCounter(int value) {  
           counter = value;  
      }  
 }  
 class D extends B, C {  
      public void doEvil() {  
           doGood();  
           System.out.println("Counter is: " + counter);  
      }  
 }  

Can you determine the output ?
No. Its not possible to determine.

The pictorial form is like below,


This is knows as Deadly Diamond of Death. Java avoids this situation by providing multiple inheritance only through Interfaces where the implementing class must override the methods of Interface and as only a class is supported to be extended so, no problem if you extend a class overriding the Interface. So, if you try to create a situation of Deadly Diamond of Death, Java simply won't allow you.

Check the following, it has no problem though it supports multiple inheritance.

 interface A {  
      public void doGood();  
      public void doA();  
 }  
 interface B {  
      public void doGood();  
      public void doB();  
 }  
 class C implements A, B {  
      @Override  
      public void doB() {  
           // TODO Auto-generated method stub  
      }  
      @Override  
      public void doGood() {  
           // TODO Auto-generated method stub  
      }  
      @Override  
      public void doA() {  
           // TODO Auto-generated method stub  
      }  
 }  

Even the following is also supported.

 interface A {  
      // Method must be overridden  
      void doGood();  
 }  
 class B implements A {  
      // A introduced new method  
      public void doStuff() {  
           System.out.println("Doing stuffs for A");  
      }  
      // Implementing class must override doGood()  
      @Override  
      public void doGood() {  
           System.out.println("Doing good in B");  
      }  
 }  
 class C extends B implements A {  
      // C introduced another new method  
      public void doMore() {  
           System.out.println("Doing more for C");  
      }  
      // Invoke doGood. No problem, only one implementation is there  
      public void doEvil() {  
           System.out.println("Trying to do evil in C but Java does not allow me to do");  
           doGood();  
      }  
 }  
 public class ABC {  
      public static void main(String args[]) {  
           // Create new object of C  
           C c = new C();  
           // Invoke any method of A, B and C. Inheritance is there in place and  
           // you avoid Deadly Death of Diamond  
           c.doGood();  
           c.doEvil();  
           c.doStuff();  
           c.doMore();  
      }  
 }  

Output is:
 Doing good in B  
 Trying to do evil in C but Java does not allow me to do  
 Doing good in B  
 Doing stuffs for A  
 Doing more for C  

Hope this clears your confusion why Java does not support multiple inheritance through Classes. Comments are always welcome...

Prev
Palash Kanti Kundu
Palash Kanti Kundu