Implementing a Generic Method with Function as Parameters Using Interfaces

Consider the following: Say the function getListItems() needs to download a JSON output, parse it, and return a list of items of a specific type. Depending on the URL we get the output from, we might want to parse the JSON differently. So it would make our lives much easier if we could pass the parsing function as a parameter into the getListItems() function!

I. Passing Functions as Parameters using Interfaces

Unlike C++/C (and even similarly in the likes of Python), Java does not allow one to explicitly pass functions as the arguments of functions. What one can do, however, is make use of interfaces. The idea is to create an interface with a method, and create a unique implementation of each method. Let’s see this at work:

public interface Parser{

public List<Items> parseMethod(String url);

}

public class ParserForA implements Parser{

public List<Items> parseMethod(String url){

//do something specific for A

}

}

public class ParserForB implements Parser{

public List<Items> parseMethod(String url){

//do something specific for B

}

}

Now we can  parametrize getListItems with a Parser instance! To actually use it we might do something like


public List<Items> getListItems(String url, Parser parser){

return parser.parser(url)

}

And voila! getListItems(url, new ParserForA()) will use the parsing method for A, while getListItems(url, new ParserForB()) will use the parsing method for B.

II. Using generics to return a List of any type

Now so far we have made both parsing functions return a list of items which are of the same type. Often, if the JSON parsing method is different, most likely the information that we want to be processing and extracting is different. That is, what if we want to make the parser for A return a list of ItemA, while the parser for B returns a list of ItemB? To accomplish this we must make use of generics. Here’s how we code the interface:

public interface Parser<T>{

public List<T> parseMethod(String url);

}

public class ParserForA implements Parser<A>{

public List<A> parseMethod(String url){

//do something specific for A

}

}

public class ParserForB implements Parser<B>{

public List<B> parseMethod(){

//do something specific for B

}

}

Now for the actual getListItems function, we can use the following syntax to establish a generic method:


public <T> List<T> getListItems(String url, Parser<T> parser){

return parser.parser(url)

}

And now the compiler will be happy when we claim that getListItems(url, new parserForA()) returns a List (and likewise for B)!

Advertisements
This entry was posted in Programming and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s