Java8 Lambdas

Default methods aspect oriented programming on JPA entities

When working with entity classes it is common not to add additional logic to the objects. This avoids dependencies in the code to keep it modular and maintainable. With default methods it is possible to enhance the entities in a simple way without affecting the original notion of a business object that just keeps the data.

Usually the entities are loaded from a database via the persistence layer, and are then used within the runtime context of the application. Modern frameworks provide descriptive mechanisms to define which entity attributes are to be displayed within the controls of the user interface.

public class Person {

    @NotNull
    @Size(min = 3, max = 40)
    private String firstName;
    private String name;
    
    @NotNull
    private Date birthday;

}

If the Person entity is to be displayed in a GUI the programmer only declares the columns of the table with the names of the class attributes. Modern frameworks then automatically load the values from the databean and display them in the user interface.

  public Date getBirthday() {
     return birthday;
  }
  
  public int getAgeInYears() {
     long ageInMillis = System.currentTimeMillis() - getBirthday().getTime();
     Calendar cal = Calendar.getInstance();
     cal.setTimeInMillis(ageInMillis);
     return cal.get(Calendar.YEAR);
  }

In the above example the age of a person is an aspect of the person class that can be derived from the current date and the persons birthday. Adding such a method will enable the framework to also show the current age. However it is these kind of methods that make the code harder to maintain as they are usually scattered around in several places of code. At best the developers have managed to put them into a common utility class. (which is used as a library in different versions throughout the project..) .

To generally avoid adding logic to the entity class by introducing a getter as shown one declares it as an adapter in the GUI logic. That way the birthday is converted to the age by the presentation layer.

interface AgeAspect {
  
  Date getBirthday();
  
  /**
   * See also 
   * {@linkplain https://stackoverflow.com/questions/1116123/how-do-i-calculate-someones-age-in-java}
   * @return the age in years relative to today
   */
  default int getAgeInYears() {
     long ageInMillis = System.currentTimeMillis() - getBirthday().getTime();
     Calendar cal = Calendar.getInstance();
     cal.setTimeInMillis(ageInMillis);
     return cal.get(Calendar.YEAR);
  }	
}

public class Person implements AgeAspect {

    @NotNull
    @Size(min = 3, max = 40)
    private String firstName;
    private String name;
    
    @NotNull
    private Date birthday;

    public Date getBirthday() {
       return birthday;
    }
}

With the new default methods introduced in Java 8 one can enhance every class that has a getBirthday() method can be amended with the age aspect by simply implementing the interface and without breaking any existing inheritance hierarchies.

The Viritin library that adds functionality for JPA entities in the Vaadin web app gui framework will soon have support for default methods, see pull request here.

Currently most frameworks do not support calling the default methods and the introspection only determines normal properties of classes. However the regular reflection api introduced in Java 4 is fully sufficient to implement this functionality therefore the libraries supporting it are still compatible with older Java releases.

Hopefully more library implementations such as the apache commons beanutils will support default methods soon.

Spliterator for “in-between” lambda processing

The usecase of summing up the distances in a list of vectors can benefit from parallelization on todays multi-core systems with Java 8 lambdas using a Spliterator.

If one writes

vecList.stream().mapToDouble( e-> 
    e.getDistance( b )

Then a reference to the next point “b” isn’t there hence the calculation cannot be performed that way. There is a property of each list item, it has a relation to the previous and a relation to the next item in the list.

Expressed as a piece of java code it might look as simple as this

final class Relation<T> {
   private final T a;
   private final T b;
   public Relation(T t0, T t1) {
      this.a = t0;
      this.b = t1;
   }
   public T getA() {
      return a;
   }
   public T getB() {
      return b;
   }
}

If we iterate on the relation organizing the list items into pairs, a distance calculation is possible by using a lambda expression and the stream api.

double totalDistance = stream.mapToDouble(
   e -> {
      return e.getA().distance(e.getB());
   }).sum();

To get there, a Spliterator class has to be defined that provides items for processing when the lambda expression is evaluated and is also capable of dividing the remaining set of items into subsets (sub-lists in this case) for parallel processing. Here is a possible implementation:

/**
 * A provider for pairs of consecutive list items
 *
 * @param <T>
 */
public class PairIterator<T> implements Spliterator<Relation<T>> {

 private final List<T> list;

 private int index;
 private final int start;
 private int end;
 
 /**
  * Allows to iterate over elements and their successors
  */
 public PairIterator(List<T> list) {
    this(list, 0, list.size());
 }

 /**
  * Internally used when the iterator is being split
  */
 private PairIterator(List<T> list, int start, int end) {
    this.list = list;
    this.start = index = start;
    this.end = end;
 }
 /**
  * Creates a new Relation between two consecutive items and 
  * performs the {@link Consumer#accept(entry)} operation. 
  */ 
 @Override
 public boolean tryAdvance(Consumer<? super Relation<T>> action) {
    Relation<T> entry;
    if (index >= end || index >= list.size()-1) {
       return false;
    }
    entry = new Relation<T>(list.get(index), list.get(++index));
    action.accept(entry);
    return true;
 }

 /**
  * If the list still has more that 4 elements to be processed
  * the method splits the work items into two working sets of ordered elements
  */ 
 @Override
 public PairIterator<T> trySplit() {
    int size = end - index;
    if (size > 4) {
       //reuse the middle element for both sides, so pair(mid-1,mid) and pair(mid,mid+1) is created 
       int mid = start + (size >> 1);
       int prevEnd = end;
       end = mid;
       return new PairIterator<T>(list, mid, prevEnd);
    }
    return null;
 }
 /**
  * @return the size of the remaining workload
  */
 @Override
 public long estimateSize() {
    return (end - index);
 }
 /**
  * Configuration of this spliterator
  */
 @Override
 public int characteristics() {
    return Spliterator.CONCURRENT | Spliterator.SIZED | Spliterator.ORDERED;
 }
}

There are two methods in the Spliterator implementation that are used to accomplish streaming the relations of predeccessor and successor, tryAdvance and trySplit. The first actually performs the action on the item pair by instantiating a Relation  on-the-fly, and calling accept(...) where the real calculation happens. The latter contains the algorithm to distribute the workload to the consumers. If the size of the remaining elements is greater than 4 it changes the indeces pointing into the list and returns a new instance configured for the remaining indeces. The method is designed to have a list element being used in two relations, once as a sucessor and once as a predecessor, so care must be taken not to modify its state by executing code with side-effects.

To use it a Stream is constructed with the StreamSupport class by passing the Spliterator as an argument and true to ensure it is processed in parallel:

//creates a parallel stream
Stream<Relation<Vec2>> stream = StreamSupport.stream(new PairIterator<Vec2>(vecList), true);

double totalDistance = stream.mapToDouble(
  e -> {
     return e.getA().distance(e.getB());
  }).sum();