Sunday, February 19, 2012

Comparable and Generics

The Comparable interface is defined this way:
public interface Comparable<T> {
    public int compareTo(T o);
}

The interface is a little non-intuitive because the method compareTo does not take a Comparable as a parameter, but instead takes the type itself as a parameter.


Consider a algorithm to find the max item, with input being a list of items, each implementing Comparable :

public static<T> Comparable<T>  max(Collection<Comparable<T>> coll){
  Iterator<Comparable<T>> iterator = coll.iterator();
  Comparable<T> maxElement = iterator.next();
  
  while(iterator.hasNext()){
   Comparable<T> nextElem = iterator.next();
   if (nextElem.compareTo((T)maxElement) > 0 ){
    maxElement = nextElem;
   }
  }
  return maxElement;
 }

Since the input is a Comparable type, the only way to invoke a compareTo method inside this algorithm is to cast from Comparable<T> to the java type, which defeats the use of generics, a better way to get it to work is to declare the type this way - <T extends Comparable<T>> , or even better this way: <T extends Comparable<? super T>>

public static<T extends Comparable<T>> T  max(Collection<? extends T> coll){
  Iterator<? extends T> iterator = coll.iterator();
  T maxElement = iterator.next();
  
  while(iterator.hasNext()){
   T nextElem = iterator.next();
   if (nextElem.compareTo(maxElement) > 0 ){
    maxElement = nextElem;
   }
  }
  return maxElement;
 }
  
 
 @Test
 public void testMaxForASmallListOfIntegers(){
  List<Integer> arr =Arrays.asList(5,3,10,2000,15,9,2,1);
  assertThat(max(arr), is(2000));
 }

This time around the generic type declaration is <T extends Comparable<T>>, which says that T implements Comparable, and the API from a client perspective is also clean as demonstrated in the accompanying test.

Sunday, February 12, 2012

Javascript closure with iteration

This is something with Javascript that tripped me up recently:

I had a geographical US map, with the different states highlighted - I used a jquery plugin called maphilight to get the highlights working, and needed to respond to the click event on the southern US states, I had a code along these lines:
var south=["VA", "WV", "KY", "TN", "NC", "SC", "GA", "AL", "MS", "FL", "LA", "AR"];
            for (var i=0;i<south.length;i++){
                $("[title=" + south[i] + "]").click(function(){
                    alert(south[i] + " clicked");
                });
            }


This however does not work - if I click on any of the southern states, the result is actually "undefined clicked".

The reason for this behavior is the closure defined as the click handler - it has a reference to variable "i" and NOT it's value at the point of defining the function, and is resolved only at the point of calling it, which is as a response to the click event. Since it is defined within a loop, i's value at the end of the loop is 12 at the end of the loop, and is resolved as south[12] in the function, and a southern state at this index does not exist

The fix is interesting, I got it from the book - Secrets of the Javascript Ninja and is to use something called an immediate function which looks something like this:
(function(){
.....
})()

Using the immediate function, the fixed code looks like this:
var south=["VA", "WV", "KY", "TN", "NC", "SC", "GA", "AL", "MS", "FL", "LA", "AR"];
            for (var i=0;i<south.length;i++){
                (function(index){
                    $("[title=" + south[index] + "]").click(function(){
                        alert(south[index] + " clicked");
                    });
                 })(i);            

Wednesday, February 1, 2012

Spring MVC 3.1 - HandlerMethod

Spring MVC 3.1 has newly introduced the concept of a HandlerMethod. HandlerMethod is a wrapper around the method which is invoked for a user web request.

For a controller with this signature,

@Controller
@RequestMapping("/accounts")
public class AccountController {

....
 @RequestMapping(method = RequestMethod.GET)
 public String list(Model model) {
  model.addAttribute("accounts", this.accountManager.getAccounts());
  return "accounts/list";
 }

 @RequestMapping(value="/new", method = RequestMethod.GET)
 public String newForm(Model model) {
  model.addAttribute(new Account());
  return "accounts/new";
 }



a HandlerMethods map will be generated mappping the contents of the RequestMapping annotation of the method, to the HandlerMethod, something which looks like this:

path pattern: /accounts method: GET -> AccountController: list(Model)
path pattern: /accounts/new method: GET -> AccountController: newForm(Model)

Now on a user request for say for a GET on /accounts/new the appropriate HandlerMethod is retrieved from the map, and the request dispatched to the HandlerMethod.

Some of the abstractions that come into play are:
1. RequestMappingHandlerMapping - manages the map of path patterns to HandlerMethod
2. RequestMappingHandlerAdapter -  takes in a user request, transforms the request parameters into a state that is consumable by the HandlerMethod, calls the interceptors, and finally invokes the HandlerMethod


The HandlerMethod abstraction has been introduced with Spring 3.1, prior to Spring 3.1, the Handler used to be the controller class itself - when a call from a user comes in, the pattern of the request resolves upto the Controller and then a different pattern matching was performed at the level of the controller by iterating over the  Controller methods to find the right method to invoke. HandlerMethod simplifies the flow significantly by recognizing that a request mapped method is the actual handler and not the controller itself ( this is functional in a way - by making the Controller method a first class citizen).

This change from 3.0.x to 3.1.0 is significant, what I have truly appreciated about the Spring codebase is that this change is transparent to the developers - as long as the Spring MVC defaults are adhered to (using mvc:annotation-driven etc), this change of engine under the covers, just works.