Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Design Patterns and Best Practices in Java

You're reading from   Design Patterns and Best Practices in Java A comprehensive guide to building smart and reusable code in Java

Arrow left icon
Product type Paperback
Published in Jun 2018
Publisher Packt
ISBN-13 9781786463593
Length 280 pages
Edition 1st Edition
Languages
Arrow right icon
Authors (4):
Arrow left icon
Kamalmeet Singh Kamalmeet Singh
Author Profile Icon Kamalmeet Singh
Kamalmeet Singh
Lucian-Paul Torje Lucian-Paul Torje
Author Profile Icon Lucian-Paul Torje
Lucian-Paul Torje
Sumith Kumar Puri Sumith Kumar Puri
Author Profile Icon Sumith Kumar Puri
Sumith Kumar Puri
Adrian Ianculescu Adrian Ianculescu
Author Profile Icon Adrian Ianculescu
Adrian Ianculescu
Arrow right icon
View More author details
Toc

Table of Contents (11) Chapters Close

Preface 1. From Object-Oriented to Functional Programming FREE CHAPTER 2. Creational Patterns 3. Behavioral Patterns 4. Structural Patterns 5. Functional Patterns 6. Let's Get Reactive 7. Reactive Design Patterns 8. Trends in Application Architecture 9. Best Practices in Java 10. Other Books You May Enjoy

Functional programming

Functional programming is a sub-paradigm of declarative programming. As opposed to imperative programming, functional programming does not change the internal state of the program.

In imperative programming, the functions can be regarded more as sequences of instructions, routines, or procedures. They not only depend on the state stored in the memory but can also change that state. This way, invoking an imperative function with the same arguments can produce different results depending on the current program's state, and at the same time, the executed function can change the program's variables.

In functional programming terminology, functions are similar to mathematical functions, and the output of a function depends only on its arguments, regardless of the program's state, which, at the same time, remains unaffected by the execution of the function.

Paradoxically, while imperative programming has existed since computers were first created, the basic concepts of functional programming dates back before that. Most functional languages are based on lambda calculus, a formal system of mathematical logic created in the 1930s by mathematician Alonzo Church.

One of the reasons why functional languages become so popular in those days is the fact that they can easily run in parallel environments. This should not be confused with multithreading. The main feature that allows functional languages to run in parallel is the basic principle on which they reside: the functions rely only on the input arguments and not on the program's state. That is, they can be run anywhere, and the results of the multiple parallel executions are then joined and used further.

Working with collections versus working with streams

Everyone working with Java is aware of collections. We use collections in an imperative way: we tell the program how to do what it's supposed to do. Let's take the following example in which we instantiate a collection of 10 integers, from 1 to 10:

List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++)
{
list.add(i);
}

Now, we will create another collection in which we will filter in only the odd numbers:

List<Integer> odds = new ArrayList<Integer>();
for (int val : list)
{
if (val % 2 == 0)
odds.add(val);
}

At the end, we want to print the results:

for (int val : odds)
{
System.out.print(val);
}

As you can see, we wrote quite a bit of code to perform three basic operations: to create a collection of numbers, to filter the odd numbers, and then to print the results. Of course, we could do all the operations in only one loop, but what if we could do it without using a loop at all? After all, using a loop means we tell the program how to do its task. From Java 8 onwards, we have been able to use streams to do the same things in a single line of code:

IntStream
.range(0, 10)
.filter(i -> i % 2 == 0)
.forEach( System.out::print );

Streams are defined in the java.util.stream package, and are used to manage streams of objects on which functional-style operations can be performed. Streams are the functional correspondent of collections, and provide support for map-reduce operations.

We will further discuss streams and functional programming support in Java in later chapters.

You have been reading a chapter from
Design Patterns and Best Practices in Java
Published in: Jun 2018
Publisher: Packt
ISBN-13: 9781786463593
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime