org.jutil.java.collections
Class Accumulator

java.lang.Object
  |
  +--org.jutil.java.collections.Accumulator
All Implemented Interfaces:
CollectionOperator

public abstract class Accumulator
extends java.lang.Object
implements CollectionOperator

A class of objects that accumulate over a collection.

The Accumulator class is the general class for visiting a collection while passing some object to the next element. The original collection remains unchanged. In relational algebra, this is aggregation.

The initial object is returned by the initialAccumulator() method and passed to the accumulate(Object element, Object acc) method. This method then returns the object to be given to the next element and so on. The object returned by the visit of the last element of the collection is returned to the user. The accumulation is started by invoking the accumulate(Collection collection) method.

An example of an accumulation is shown below. It is used to calculate the state of a list of components based on the state of its components. The traditional code is also shown.

Accumulation the traditional way.


 Iterator iter = collection.iterator();
 MyType myAccumulator = (* initial value *);
 while(iterator.hasNext()) {
   MyType element = (MyType) iter.next();
   myAccumulator = (* accumulation of element and myAccumulator *);
 }
 

Accumulation using the Accumulator class.


 MyType myAccumulator = 
     (MyType) new Accumulator() {
       public Object initialAccumulator() {
         return (* initial value *);
       }

       public Object accumulate(Object element, Object acc) {
         return (* accumulation of element and myAccumulator *);
       }
     }.accumulate(collection);
 

The same, but now with specifications.


 MyType myAccumulator = 
     (MyType) new Accumulator() {
      /oo
        o also public behavior
        o
        o post (* preconditions for accumulate *);
        o
        o public model boolean isValidElement(Object element);
        oo/

      /oo
        o public behavior
        o
        o post \result = (* initial value *);
        oo/
       public Object initialAccumulator() {
         return (* initial value *);
       }

      /oo
        o public behavior
        o
        o post \result = (* accumulation of element and myAccumulator *);
        oo/
       public Object accumulate(Object element, Object acc) {
         return (* accumulation of element and myAccumulator *);
       }
     }.accumulate(collection);
 

The Jutil.org version requires slightly more code, but is easier to understand than the traditional code because there are no control statements anymore.

Version:
$Revision: 1.12 $
Author:
Jan Dockx, Marko van Dooren

Field Summary
static java.lang.String CVS_REVISION
           
 
Constructor Summary
Accumulator()
           
 
Method Summary
 java.lang.Object accumulate(java.util.Collection collection)
          public behavior

pre (\forall Object o, collection.contains(o); isValidElement(o));

post (* the result of the accumulation is returned *);
post collection == null => \result == initialAccumulator();

signals (ConcurrentModificationException) (* The collection was modified while accumulating *);
abstract  java.lang.Object accumulate(java.lang.Object element, java.lang.Object acc)
          public behavior

pre isValidElement(element);
abstract  java.lang.Object initialAccumulator()
          Subclasses should implement this method to return the initialized accumulator.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

CVS_REVISION

public static final java.lang.String CVS_REVISION
Constructor Detail

Accumulator

public Accumulator()
Method Detail

initialAccumulator

public abstract java.lang.Object initialAccumulator()

Subclasses should implement this method to return the initialized accumulator. This method is called at the start of the accumulation. The result will be used in the application of public Object accumulate(Object element, Object acc) for the first element.


accumulate

public abstract java.lang.Object accumulate(java.lang.Object element,
                                            java.lang.Object acc)
public behavior

pre isValidElement(element);

This method is called for each element in the collection we are accumulating. Subclasses should implement this method to process and accumulate the result in .

The result is the accumulator that will be used for the next element of the collection to process.

. //MvDMvDMvD : names aren't clear : accumulator is not an Accumulator
Parameters:
element - The object the method will process and change the accumulator with.
acc - The accumulator for the accumulation. For the first element to be processed, the result of initialAccumulator is used. For the other elements, the result of this method applied on the previous element is used.

accumulate

public final java.lang.Object accumulate(java.util.Collection collection)
                                  throws java.util.ConcurrentModificationException
public behavior

pre (\forall Object o, collection.contains(o); isValidElement(o));

post (* the result of the accumulation is returned *);
post collection == null => \result == initialAccumulator();

signals (ConcurrentModificationException) (* The collection was modified while accumulating *);

Perform the accumulation defined in public Object accumulate(Object element, Object acc) for each element of . For the first element, the object returned by public Object initialAccumulator() is used as accumulator. For the other elements, the result of the application of public Object accumulate(Object element, Object acc) on the previous element is used as accumulator.

The contents of is not changed.

The result of this method is the object returned by the application of public Object accumulate(Object element, Object acc) on the last element of the collection to be processed.

Parameters:
collection - The collection to perform this accumulation on. It will not be changed. This can be null, in which the initial accumulator is returned.