Article: Functional programming in Java
In addition to the usual set of concepts like OO programming, and AOP (Aspect Oriented Programming), the functional programming offers a different way to think about software and solve some of the problems. For example, manipulating a collection of objects and mathematical computations. Java is not a functional programming language. Scala, Clojure, and Groovy are functional programming languages and run on the JVM and can interact with legacy Java classes. Programming with multiple programming languages like Java, Scala, Clojure, and Groovy is known as the polyglot programming. |
This article focuses on how you can implement functional programming in Java with some verbosity. You can't do the following in Java to iterate through a collection of items and print each item
items.each(new Function() { public void apply(String item) { System.out.println("print:" + item); }})But, you can achieve the similar results in Java as shown below:
import java.util.Arrays; import java.util.Iterator; import java.util.List; public class FuncProg { public static void main(String[] args) { //list of Java technologies List<String> items = Arrays.asList("Java", "JEE", "JDBC", "JMS"); new Functional<String>().each(items, new FuncProg.Function<String>() { @Override public void apply(String item) { System.out.println("print: " + item); } }); } //inner functional class. This could be defined as a separate outer class public static class Functional<T> { public void each(final Iterable<T> items, final Function<T> f){ Iterator<T> it = items.iterator(); while(it.hasNext()){ f.apply(it.next()); } } } //interface for the function public interface Function<T> { void apply(T item); } }
Hmmm, you might think that the above functionality can be easily implemented by having two methods perform the relevant tasks. The true functional programming languages have much more concise syntax to achieve this. The real power of functional programming is realized when you want greater reuse of the functions as demonstrated below with Java code. You can have different combinations of iterating through a collection and computing each item in the collection. The Functional class provides different possible iteration logic and the Function interface provides different way to compute each item.
Step 1: Define the interface that applies some functionality to each item.
public interface Function<T> { void apply(T item); }
Step 2: Define the class that can process a collection in different ways.
import java.util.Iterator; public final class Functional<T> { public void each(final Iterable<T> items, final Function<T> f) { Iterator<T> it = items.iterator(); while (it.hasNext()) { f.apply(it.next()); } } public void eachSecondItem(final Iterable<T> items, final Function<T> f) { Iterator<T> it = items.iterator(); int i = 0; while (it.hasNext()) { T item = it.next(); // every second item if (i % 2 == 0) { f.apply(item); } ++i; } } }
Step 3: Finally the sample test class and the implementations of the Function interface.
import java.util.Arrays; import java.util.List; public class FuncProg { public static void main(String[] args) { //list of Java technologies List<String> items = Arrays.asList("Java", "JEE", "JDBC", "JMS", "XML"); //print each item: Function is defined as anonymous inner class but can be extracted to its own class new Functional<String>().each(items, new PrintFunction<String>()); //print items that are abbreviation like JEE, JDBC, JMS new Functional<String>().each(items, new PrintAbbreviationFunction<String>()); //print every second item new Functional<String>().eachSecondItem (items, new PrintFunction<String>()); //print every second abbreviated item new Functional<String>().eachSecondItem (items, new PrintAbbreviationFunction<String>()); } //Inner class. This could be in its own separate class static class PrintFunction<T> implements Function<T> { @Override public void apply(T item) { System.out.println("print: " + item); } } //Inner class. This could be in its own separate class static class PrintAbbreviationFunction<T> implements Function<T> { @Override public void apply(T item) { char[] chars = ((String)item).toCharArray(); boolean allCaps = true; for (Character charVal : chars) { if(Character.isLowerCase(charVal)){ allCaps = false; break; } } if(allCaps){ System.out.println("print abbrevated item: " + item); } } } }
The output for the above code is:
print: Java print: JEE print: JDBC print: JMS print: XML print abbrevated item: JEE print abbrevated item: JDBC print abbrevated item: JMS print abbrevated item: XML print: Java print: JDBC print: XML print abbrevated item: JDBC print abbrevated item: XML
So, understanding functional programming is very useful.If you want true functional programming, with closures and functions as first class objects, pick another language. Scala, Clojure, Groovy all run on the JVM and can interact with legacy Java classes. This knowledge will be handy in writing code in JavaScript where functions are first class objects and can be referenced and passed around. In functional programming, you need to grasp the concepts like functions as first-class values, currying, immutable values, and closures. Look at the JavaScript examples for better understanding of functional programming.
Here is another example of creating a closure in Java as shown below:
public class JavaClosure { public static void main(String[] args) { //Create a closure with an anonymous inner class Runnable workerThreadObject = new Runnable() { @Override public void run() { System.out.println("Printed from a newly created worker thread '" + Thread.currentThread().getName() + "'"); } }; System.out.println("Printed from main thread '" + Thread.currentThread().getName() + "' that is always started by the JVM."); JavaClosure jc = new JavaClosure(); jc.callAnotherMethod(workerThreadObject); } private void callAnotherMethod(Runnable workerThreadObject) { //invoke the closure method on the object that gets passed around Thread thread1 = new Thread(workerThreadObject); thread1.start(); //calls the run method in the closure } }
The output will be
Printed from main thread 'main' that is always started by the JVM. Printed from a newly created worker thread 'Thread-0'
Closures are very common in JavaScript and you can learn more about JavaScript closures.
Labels: Core Java
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home