Thursday, 28 July 2011

Best practices while using collection API

The following are some best practices that one can follow while using collection API (as discussed in various blogs and books)

  1. Code to interfaces rather than implementation; reason, you can change the implementation later on without significant effect.
  2. Set the initial capacity of the collection appropriately, if you know the size you can gain on speed, else these collection classes will have to grow periodically when the size hits the limit.
  3. Use ArrayList, HashMap etc as opposed to Vector and Hashtable; reason,Vector and Hashtable methods are synchronized, if you want synchronization using ArrayList, HashMap then you externally synchronize the same. I will show that in my next blog.
  4. Return zero length collection or array as opposed to returning NULL; to avoid running into NullPointerException issues at runtime.
  5. Immutable object should be used as keys for the HashMap; so also as values in a HashSet. 
  6. Encapsulate collections; to avoid unintentional  modification of the collections.
  7. Stored related objects together and avoid storing unrelated or different types in the same collection.

Overriding and overloading a method

So what do we understand by these two terms.

Overriding, lets you define the same method in different ways for different object types in an hierarchy (i.e  when there is inheritance, hence we can say a subclass can override the behavior defined in the super class). The general rules to override a method are
  1. The method MUST have the same argument list.
  2. The method MUST have the same return type.
  3. The access modifier CANNOT be less restrictive
  4. The new method should not throw new and broader exceptions; it can throw less, narrower and run-time exception. If you throw broader exception; you violate the contract defined in the super class and and also you will loose the message the actual exception has to offer  
  5. Selection among overridden methods is dynamic (decision at run-time based on the object type).
In overloading,overloading lets you define the same method in different ways for different data in the class or its subclass. The general rules to overload a method are.
  1. The method MUST have different arguments (the number of arguments/type of argument can vary)
  2. The return type CAN be changed
  3. The access modifier CAN be changed
  4. The new method CAN throw different exceptions list.
  5. Selection among overloaded methods is static (made at compile time). Ex Say you have two methods print one which takes argument as Object and another print method which takes String. When the client invokes the print method with a string "Test"; then the print method which takes String will get invoked even though String extends Object, reason the decision to call the method happened at compile time. i.e  someObject. print("Test").
References
  • Effective Java  - Joshua Bloch.


    Tuesday, 26 July 2011

    Comparable versus Comparator

    Comparable and Comparator are both used to compare objects.

    In case of Comparable interface,
    1. The object o1 (class of which implements the interface) is compared to the object o2 which is passed as method argument [NOTE: public int compareTo(Object o2) ]
    2. If the o1 is greater than o2 then the method will return +ve integer and -ve if lesser than o2, if both are equal then 0 value is returned.
    3. It should be used when you want to define natural/default ordering of a class, if the class is available for modification (remember? a third party class isn't available for modification)
    4. if one add two keys a and b such that (!a.equals(b) && a.compareTo(b)==0) to a sorted set that does not use an explicit comparator, then the second add operation returns false (and the size of the sorted set does not increase) because a and b are equivalent from the sorted set's perspective.
    In case of Comparator interface,
    1. The Class which implements this interface will take two objects and compare them with each other. [NOTE: public int compare(Object o1, Object o2)
    2. If the o1 is greater than o2 then the method will return +ve integer and -ve if lesser than o2, if both are equal then 0 value is returned.
    3. If the class isn't available for modifying or if you want to define ordering which is other than the default then use the Comparator interface.
    4. If one add two keys a and b such that (a.equals(b) && c.compare(a,b)!=0) to a sorted set with comparator c, then the second add operation returns false (and the size of the sorted set does not increase) because a and b are equivalent from the sorted set's perspective.
    Resources

    Monday, 25 July 2011

    Abstract class and interface

    When to create abstract class?
    We create an abstract class when there is some common behaviour which can be reused across subclasses and certain behaviour needs to be defferred to the sublasses as they are subclass specific. We define such a behaviour using the abstract construct in java. Abstract classes help us achieve implementation inheritance.
    When to create an interface?
    When the client is only concerned with the behavior and does not worry about the actual implementation, then we should model such behavior using interface. Interface helps us achieve polymorphic interface inheritance.

    So having said that,
    1. Abstract classes should be used when there is a strict heirarchy of classes i.e there is strict IS-A relationship between the classes. Ex FlatFileReader/XMLFileReader extends FileReader method loadFile is common behaviour and the procedure to load a flat file versus a XML file is the same however readFile can be sublass specific given the file types. With interface you can relate classes which are otherwise unrelated.
      Ex SoundBehaviour interface with method makeSound() can relate a Animal Class heirachy and Instrument class heirachy.
    2. Abstract classes should be used in cases where the base class needs to be changed often, the subclasses will inherit the behaviour without any change.Use of interfaces in such a case will make the design fragile, as changes to interfaces will be propogated to implementing classes.
    Resources