Sunday, October 21, 2012

Array, ArrayList, ListCollectionView and ArrayCollection

Few days back I got stuck with one minor but pretty confusing problem. I was getting an ArrayList from java as a remote call and I assigned that event.result to the ArrayCollection in Flex. And I was using the same arraycollection at three different places. At one place I was showing all the items in the arraycollection and at other places I was applying some filter function. It all seemed ok, but there was some logic which was performing search at one place and at some other places it was trying to perform some addition/deletion/update work on the items in the collection. But some times I observed weird behavior: after doing the search at one place I was getting the index and trying to remove the element at that index at second place from the same collection and it resulted into range error exception. That was surprising!!


Then after some debugging I realized that the filter function applied at second place, actually changes the elements of the arraycollection but the underlying source (array) remains intact. But I want to have a solution which will allow me to use the same collection at multiple times, along with the option that I can apply filter at one place without disturbing the list of items at other place. Also if I do insertion/deletion at any one place, the other should be updated as well. So I came with the idea of exploring all of them. One very useful post I found here.and here. Let's proceed.

Array: Similar to array in any other language. It stores a list of references to other objects. It is zero-based (like java) and is unbounded (means automatically grow when items are added). Unfortunately we cannot peek into the source class for this. More

 // create an empty array then add elements
   var array1:Array = new Array();
   array1[0] = "A";
   array1[1] = "B";
   array1[2] = "C";
   trace( "Array has " + array1.length + " elements" ); // returns 3

To loop over an array in action script we can find an example here

ArrayList: An ArrayList wraps an array with the name source (note that it does not extend Array but wraps it) and adds event listeners to all of its items. It extends EventDispatcher class so, when the items are added/deleted/updated it dispatches proper event so that the component (List, DataGroup etc) can update itself.

public class ArrayList extends EventDispatcher  implements IList,IExternalizable, IPropertyChangeNotifier
{
           private var _source:Array;

           public function get source():Array
           {
              return _source;
           }
    
           public function set source(s:Array):void
           {
              var i:int;
              var len:int;
              if (_source && _source.length)
              {
                 len = _source.length;
                 for (i = 0; i < len; i++)
                 {
                    stopTrackUpdates(_source[i]);
                 }
              }
             _source  = s ? s : [];
             len = _source.length;
             for (i = 0; i < len; i++)
             {
                   startTrackUpdates(_source[i]);
             }
        
             if (_dispatchEvents == 0)
             {
                   var event:CollectionEvent =
                   new  CollectionEvent(CollectionEvent. 
                     COLLECTION_CHANGE);
                   event.kind = CollectionEventKind.RESET;
                   dispatchEvent(event);
             }
         }

}
If the item in the ArrayList is IEventDispatcher the startTrackUpdates and stopTrackUpdates methods will start or stop tracking the updates for the item.




ListCollectionView: It wraps (and not extends) the ArrayList (which implements IList interface, explained later on) and provides filtering, sorting and cursor functionality.

public class ListCollectionView extends Proxy implements ICollectionView, IList, IMXMLObject
{
   private var _list:IList;
   public function get list():IList
    {
        return _list;
    }
    public function set list(value:IList):void
    {
        if (_list != value)
        {
            var oldHasItems:Boolean;
            var newHasItems:Boolean;
            if (_list)
            {
               _list.removeEventListener(CollectionEvent.
               COLLECTION_CHANGE,listChangeHandler);
                oldHasItems = _list.length > 0;
            }

            _list = value;

            if (_list)
            {
               // weak listeners to collections and dataproviders
        _list.addEventListener(CollectionEvent.
            COLLECTION_CHANGE,listChangeHandler, false, 0, true);
                newHasItems = _list.length > 0;
            }

            if (oldHasItems || newHasItems)
                reset();
            dispatchEvent(new Event("listChanged"));
        }
    }
}

When a filter is applied, all the items internally remained untouched, but it is just the outer code cannot see them (hence the name collection View).It means if a component is using ListCollectionView as data provider only the items passing the filtering will be shown by the component.

ArrayCollection: ArrayCollection extends ListCollectionView and inherits all the attributes and introduces a n array with name source. Internally it will wrap this array to arraylist and from there on wards its all in hands of ListCollectionView.

public class ArrayCollection extends ListCollectionView implements IExternalizable
{
       .........
       .........
       public function set source(s:Array):void
      {
            list = new ArrayList(s);
       }

}

That's all. I hope it was useful.




Wednesday, October 3, 2012

Implementing Singleton in Java

A singleton class will always have at most one instance and so it will be instantiated only once.

There are two primary ways to implement it:
  • using public static method and 
  • using public factory method. 
Both the approaches make use of private constructor. As the constructor is private we will generally not be able to construct an instance of this calls using new operator. But a privileged  client can invoke the private constructor reflectively with the aid of the AccessibleObject.setAccessible method. So we can create an exception if it's asked to create a second instance.


Using public static field:

// Singleton with public final field
public class God{
   public static final God INSTANCE = new God();
   private God() { ... }
   public void worshipHIM() { ... }
}


Using public static factory method:

// Singleton with static factory
public class God{
   private static final God INSTANCE = new God();
   private God() { ... }
   public static God getInstance() { return INSTANCE; }
   public void worshipHIM() { ... }
}

One advantage of the latter approach is: we can remove the singleton constraint easily without changing the API, if we want. As of Java 1.5 there is one more approach as pointed by Joshua Bloch(Effective Java, Item 3) here.

// Enum singleton - the preferred approach
public enum God{
   INSTANCE;
   public void worshipHIM() { ... }
}

Implementing singleton using first two approaches may need some extra work if we also want the class to be serializable. We need to make all the fields transient and also need to provide readResolve method. If we don't do so we will get new instance each time we de-serialize a serialized instance. So we need to add the following method to GOD class:

// readResolve method to preserve singleton property
private Object readResolve() {
   // Return the one true God and let the garbage collector
   // take care of the God impersonator.
   return INSTANCE;
}

There is one third approach as well by using enum:

public enum God {
   INSTANCE;
  public void makeAMiracle() { ..... }
}

And this is the best approach.

More can be found here: