15. What are some of the best practices relating to Java collection?

Use ArrayLists, HashMap etc as opposed to Vector, Hashtable etc, where possible to avoid any synchronization overhead. Even better is to use just arrays where possible. If multiple threads concurrently access a collection and at least one of the threads either adds or deletes an entry into the collection, then the collection must be externally synchronized. This is achieved by:

Map myMap = Collections.synchronizedMap (myMap);

List myList = Collections.synchronizedList (myList);

Set the initial capacity of a collection appropriately (e.g. ArrayList, HashMap etc). This is because collection classes like ArrayList, HashMap etc must grow periodically to accommodate new elements. But if you have a very large array, and you know the size in advance then you can speed things up by setting the initial size appropriately.

For example: HashMaps/Hashtables need to be created with sufficiently large capacity to minimise rehashing (which happens every time the table grows). HashMap has two parameters initial capacity and load factor that affect its performance and space requirements. Higher load factor values (default load factor of 0.75 provides a good trade off between performance and space) will reduce the space cost but will increase the lookup cost of myMap.get(…) and myMap.put(…) methods. When the number of entries in the HashMap exceeds the current capacity * loadfactor then the capacity of the HasMap is roughly doubled by calling the rehash function. It is also very important not to set the initial capacity too high or load factor too low if iteration performance or reduction in space is important.

Program in terms of interface not implementation: For example you might decide a LinkedList is the best choice for some application, but then later decide ArrayList might be a better choice for performance reason. Use:

List list = new ArrayList(100); //program in terms of interface & set the initial capacity.

Instead of:

ArrayList list = new ArrayList();

Avoid storing unrelated or different types of objects into same collection: This is analogous to storing items in pigeonholes without any labelling. To store items use value objects or data objects (as oppose to storing every attribute in an ArrayList or HashMap). Provide wrapper classes around your collection API classes like ArrayList, Hashmap etc as shown in better approach column. Also where applicable consider using composite design pattern, where an object may represent a single object or a collection of objects.

Avoid where possible

Better approach

The code below is hard to maintain and understand by others. Also gets more complicated as the requirements grow in the future because we are throwing different types of objects like Integer, String etc into a list just

based on the indices and it is easy to make mistakes while casting the objects back during retrieval.


List myOrder = new ArrayList()

ResultSet rs = …

While (rs.hasNext()) {

List lineItem = new ArrayList();

lineItem.add (new I nteger(rs.getInt(“itemId”)));

lineItem.add (rs.getString(“description”));

.

myOrder.add( lineItem);

}

return myOrder;


Example 2:

List myOrder = new ArrayList(10);

//create an order

OrderVO header = new OrderVO();

header.setOrderId(1001);

//add all the line items

LineItemVO line1 = new LineItemVO();

line1.setLineItemId(1);

LineItemVO line2 = new LineItemVO();

Line2.setLineItemId(2);

List lineItems = new ArrayList();

lineItems.add(line1);

lineItems.add(line2);

//to store objects

myOrder.add(order);// index 0 is an OrderVO object

myOrder.add(lineItems);//index 1 is a List of line items

//to retrieve objects

myOrder.get(0);

myOrder.get(1);


Above approaches are bad because disparate objects are stored in the lineItem collection in example-1 and example-2 relies on indices to store disparate objects. The indices based approach and storing disparate objects are hard to maintain and understand because indices are hard coded and get scattered across the

code. If an index position changes for some reason, then you will have to change every occurrence, otherwise it breaks your application. The above coding approaches are analogous to storing disparate items in a storage system without proper labelling and just relying on its grid position.



When storing items into a collection define value objects as shown below: (VO is an acronym for Value Object).


public class LineItemVO {

private int itemId;

private String productName;

public int getLineItemId(){return accountId ;}

public int getAccountName(){return accountName;}

public void setLineItemId(int accountId ){

this.accountId = accountId

}

//implement other getter & setter methods

}


Now let’s define our base wrapper class, which

represents an order:


public abstract class Order {

int orderId;

List lineItems = null;

public abstract int countLineItems();

public abstract boolean add(LineItemVO itemToAdd);

public abstract boolean remove(LineItemVO itemToAdd);

public abstract Iterator getIterator();

public int getOrderId(){return this.orderId; }

}


Now a specific implementation of our wrapper class:

public class OverseasOrder extends Order {

public OverseasOrder(int inOrderId) {

this.lineItems = new ArrayList(10);

this.orderId = inOrderId;

}

public int countLineItems() { //logic to count }

public boolean add(LineItemVO itemToAdd){

//additional logic or checks

return lineItems.add(itemToAdd);

}

public boolean remove(LineItemVO itemToAdd){

return lineItems.remove(itemToAdd);

}

public ListIterator getIterator(){ return lineItems.Iterator();}

}


Now to use:

Order myOrder = new OverseasOrder(1234) ;

LineItemVO item1 = new LineItemVO();

Item1.setItemId(1);

Item1.setProductName(“BBQ”);

LineItemVO item2 = new LineItemVO();

Item1.setItemId(2);

Item1.setProductName(“Outdoor chair”);

//to add line items to order

myOrder.add(item1);

myOrder.add(item2);



2 comments:

  1. Hi, everything is going perfectly here and ofcourse every one is sharing data, that's in fact fine, keep up writing.

    My weblog :: buy natox

    ReplyDelete