An Example of Java 8's Functional Style Programming
Nov 10, 2017
1. Overview
Java 8 introduced new libraries and programing style -- streams, functional interfaces and lambda expressions. These bring functional-style programming to the Java's object-oriented programming capabilities.
This post uses example code with these new features and shows the differences over the pre Java 8 code. The example has two programs, the first a pre Java 8 code and the second is Java 8 code. In addition, there is a non-Java program for the same example, and this is from a real functional programming language.
The example is a simple method or function that takes a non-empty string text as input and returns the number of words starting with a capital letter. The example text is "Counting the Number of Words that Begin with a Capital-letter in a String". Note there are thirteen words in the given text and six of them begin with capital letters.
Also, the example uses the recently released Java 9's Java Shell (a.k.a. JShell) to run the Java code samples.
1.1. About JShell
The Java Shell is an interactive tool for learning the Java programming language and prototyping Java code. JShell is Read-Evaluate-Print Loop (REPL), which evaluates declarations, statements, and expressions as they are entered and immediately shows the results.
The tool is available with Java 9 and is started from the operating system's command prompt. The following is a screenshot of the Java code entered into the JShell started from Windows command prompt.

A copy of the JShell's user guide can be downloaded from the Oracle JDK 9 Documentation web page: https://docs.oracle.com/javase/9/index.html
2. Java Code Examples
Create the input text string variable in the JShell:
jshell> String input = "Counting the Number of Words that Begin with a Capital-letter in a String"
input ==> "Counting the Number of Words that Begin with a Capital-letter in a String"
2.1. Pre Java 8 Code
Create a method in the JShell using pre Java 8 code. The method takes an input string and returns the number of words with capital letters as an integer.
jshell> int noOfWordsWithUppercase(String inputString) {
...> String [] words = inputString.split(" ");
...> int total = 0;
...> for (String word : words) {
...> char ch = word.charAt(0);
...> if (Character.getType(ch) == Character.UPPERCASE_LETTER) {
...> total++;
...> }
...> }
...> return total;
...> }
| created method noOfWordsWithUppercase(String)
Run the method. The method uses the variable input
(created earlier) as the argument and returns the result, 6.
jshell> int noOfWords = noOfWordsWithUppercase(input)
noOfWords ==> 6
The code uses a simple sequential for-each loop and mutative accumulation to get number of words.
2.2. Java 8 Code
Create a method in the JShell using Java 8. Run the method. Note the input text string and the results are the same as that of the example in section 2.1.Pre Java 8 Code, above.
jshell> long noOfWordsWithUppercase2(String inputString) {
...> return
...> Stream.of(inputString.split(" "))
...> .mapToInt(word -> word.charAt(0))
...> .filter(x -> Character.getType(x) == Character.UPPERCASE_LETTER)
...> .count();
...> }
| created method noOfWordsWithUppercase2(String)
jshell> long noOfWords2 = noOfWordsWithUppercase2(input)
noOfWords2 ==> 6
Note this code is easier to read and maintain compared to the code written with pre Java 8 code. The code shows what it does rather than the how -- an important aspect of functional programming.
This code is of Java 8's functional style programming and the API's are from the java.util.stream.Stream
. It has lambda expressions which are input functions to the Stream
's methods map
and filter
. The lambda's are instances of java.util.function.Function
and Predicate
functional interfaces respectively.
Here is the link to the Java SE 8 API: https://docs.oracle.com/javase/8/docs/api/
The filter
and mapToInt
are intermediate stream operations and are lazy. The count
method, a terminal operation, is a reduction. The code is an example of a reduction -- reduces the stream to a primitive.
The code uses the filter/map/reduce operations ubiquitous with functional programming.
The code is stateless and is amenable for parallel execution (given a substantial input). The Stream
's parallel
method converts the sequential stream into a parallel stream. Parallel execution is affected by factors like statelessness, side-effects, ordering and non-interference. The code converted to execute using a parallel stream is as follows:
Stream.of(inputString.split(" "))
.parallel()
.mapToInt(
...
3. The Example using Haskell
3.1. About Haskell
Haskell is a general purpose, lazy, purely functional programming language.
Haskell provides higher-order functions, non-strict semantics, static polymorphic typing, user-defined algebraic datatypes, pattern-matching, list comprehensions, a module system, a monadic I/O system, and a rich set of primitive datatypes, including lists, arrays, arbitrary and fixed precision integers, and floating-point numbers.
More about Haskell at haskell.org
3.2. Example Code
The example code is entered and run from the GHCi (Glasgow Haskell Compiler interactive) -- a REPL tool for Haskell.
ghci> :module + Data.Char
ghci> let capCount = length . filter (isUpper . head) . words
ghci> let input = "Counting the Number of Words that Begin with a Capital-letter in a String"
ghci> capCount input
6
The first line imports the module Data.Char
. The following three lines of code define the function and the input data and then run the function.
The initial line is a definition of a user-defined function, capCount
. It uses various Haskell in-built functions -- length, filter, isUpper, head and words; all these are imported by default from the Prelude
module, except the isUpper
which is from the Data.Char
. The next line defines the input string as input
. The last line runs the capCount
function with input
as argument and returns the result, 6.
The Haskell example code is taken from the online tutorial, Real World Haskell: http://book.realworldhaskell.org/read/functional-programming.html
The following is a screenshot of the GHCi for Windows with the example code:

3.3. Function Description
About strings: Note that in Haskell there is a character data type, Char
; and there is no string data type. A list of characters is a string. For example, the string "cap" is a list of characters and is same as ['c','a','p']
and has a size of 3.
- words - takes an input text string with multiple words and returns a list of word strings; this is a special string handling function. E.g.,
ghci> words "Hello world"
returns["Hello", "world"]
- filter - takes a predicate function and is applied to a list of elements of any type (in this example, strings) and returns a list of matched elements. E.g.,
ghci> filter (>3) [3,4,5]
returns[4,5]
- length - takes a list of any type and returns its size as an integer. E.g.,
ghci> length [1,2,3,5,9]
returns5
- head - takes a list of any type and returns the first element; in this example the first character of a word string. E.g.,
ghci> head "Hello"
returns'H'
- isUpper - takes a character and returns a boolean True or False depending whether the character is of uppercase or not; this is a character function. E.g.,
ghci> isUpper 'e'
returnsFalse
NOTE: "e.g." is an abbreviation for the Latin word "exempli gratia", which means "for example".
The period (.) used in the definition of the function capCount
is a function composition operator. capCount
definition is a composition of the various built-in functions. The style of writing functions using function composition is called as point-free style. Composing two functions f
and g
produces a new function that, when called with a parameter x
, is the equivalent of calling g
with the parameter x
and then calling the f
with that result:
(f.g)x
is the same asf(g(x))
Consider the following code run from the GHCi. It checks if the first character of the given string is a capital letter and returns a boolean True or False. The solution uses two built-in functions -- isUpper
and head
.
ghci> isUpper (head "Caps")
True
The same functionality using function composition:
ghci> (isUpper . head) "Caps"
True
In Java 8, function composition is available from various pre-defined functional interfaces, e.g., the java.util.function.Function
interface's andThen
and compose
default methods.
3.4. Using $ Operator
The Haskell code from the section 3.2.Example Code, can also be written akin to the Java 8 example, using the function application with a dollar ($) operator.
ghci> length $ filter isUpper $ map head $ words input
6
The code is run from the GHCi and uses the same input
variable defined earlier and returns the result, 6.
In the above code the right most function (words) is evaluated first and its result is input to the next right most function (map) separated by the $, and so on; note the functions are separated by the $ operator. Function application using $ is right associative in Haskell.
Note this version of the code uses an additional built-in function, map
.
The map
takes a function (built-in or user-defined) and a list of any type as its arguments and returns a list with its elements transformed by the function argument; in the example above the map
function returns a list of the first characters of all the string words. An example of using map
:
ghci> map (+1) [1,99,0]
[2,100,1]
Return to top