Functional Java: How to use a List in a functional way vs the imperative way

In my previous blog, we discussed how we can traverse a list in a functional way. There, first, we saw how we can do it in an imperative way and then moved ahead by modifying the code to reach the functional way. In this blog, we will explore some more uses cases of a list in a functional way and will compare it with the imperative way.

So let’s start.

We will be using the below list here:

final List<String> players = Arrays.asList("Virat", "Rohit",
 "Shikhar", "Rahul", "Rishabh", "Hardik", "MSD");

Transforming a list:

Convert a list of names to all capital letters.

Imperative:

 final List<String> uppercaseNames = new ArrayList();
        for(String player : players) {
            uppercaseNames.add(player.toUpperCase());
        }

Functional:

List<String> uppercaseNames = players.stream()
        .map(String::toUpperCase).collect(Collectors.toList());

In an imperative way, we are creating a new list and then mutating it in the loop while in the functional approach, there is no mutation and the code is very clean.

Filter elements from a list:

From a list of players, let’s pick the ones that start with the letter R.

Imperative:

final List<String> startsWithR = new ArrayList<String>();

for (String player : players) {
    if (player.startsWith("R")) {
        startsWithR.add(player);
    }
}

Functional:

List<String> startsWithR = players.stream().
        filter(player -> player.startsWith("R"))
        .collect(Collectors.toList());

Here, in an imperative way, we are again mutating a newly created list while there is no mutation in a functional way.

Picking an element from the list:

Let’s create a method that will look for an element that starts with a given letter, and prints it

Imperative:

public static void pickName(
        final List<String> players, final String startingLetter) {
    String foundName = null;
    for (String player : players) {
        if (player.startsWith(startingLetter)) {
            foundName = player;
            break;
        }
    }

    System.out.print(String.format("A name starting with %s: ", startingLetter));
    if (foundName != null) {
        System.out.println(foundName);
    } else {
        System.out.println("No name found");
    }
}

Functional:

public static void pickName(
        final List<String> names, final String startingLetter) {
    final Optional<String> foundName =
            names.stream()
                    .filter(name ->name.startsWith(startingLetter))
                    .findFirst();
    System.out.println(String.format("A name starting with %s: %s",
            startingLetter, foundName.orElse("No name found")));
}

You can see, the functional way is very clear and concise. We have used break in an imperative way and then later added the If condition to check the value of foundName variable while in a functional way, it is a very clean and simple approach where we have used Optional.

Joining Elements:

Let’s make a comma-separated string by joining the elements of List and print it.

Imperative:

String names = "";
for (int i = 0; i < players.size() - 1; i++) {
    names += players.get(i) + ", ";
}

if(players.size() > 0)
    names += players.get(players.size() - 1);

System.out.println(names);

Functional:

Approach 1:

String names = players.stream().collect(Collectors.joining(", "));
System.out.println(names);

Approach 2:

String names = String.join(", ", players);
System.out.println(names);

In an imperative approach, we had to use the normal for loop just to iterate before the last element and then later added the last element explicitly just to avoid the extra comma at the end while the functional approach is very neat and clean.

Conclusion:

As a conclusion, we get the following benefits by using functional approach:

  • Need to write less code
  • Code is maintainable
  • No mutability
  • More focus on business logic instead of writing the basic coding
  • and many more.

That’s it. Hope this blog will be helpful to give you a better understanding of using List in a functinal way. Stay tuned !!!

About Rishi Khandelwal

Rishi is a tech enthusiast with having around 10 years of experience who loves to solve complex problems with pure quality. He is a functional programmer and loves to learn new trending technologies. His leadership skill is well prooven and has delivered multiple distributed applications with high scalability and availability by keeping the Reactive principles in mind. He is well versed with Scala, Akka, Akka HTTP, Akka Streams, Java8, Reactive principles, Microservice architecture, Async programming, functional programming, distributed systems, AWS, docker.
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a comment