Skip to content

Commit 3df78ee

Browse files
committed
third article in the series
1 parent de7a715 commit 3df78ee

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

app/pages/learn/01_tutorial/03_getting-to-know-the-language/03_refactoring_to_functional_style/00_refactoring.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ In this series we cover the following conversions from the imperative to the fun
2121
|------------------------------------------------------|-----------------|------------------------------|
2222
| [Converting Simple Loops](id:refactoring.simple.loops) | `for()` | `range()` or `rangeClosed()` |
2323
| [Converting Loops with Steps](id:refactoring.loops.withsteps) | `for(...i = i + ...)` | `iterate()` with `takeWhile()` |
24+
| [Converting foreach with if](id:refactoring.foreach.withif) | `foreach(...) { if... }` | `stream()` with `filter()` |
2425

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
id: refactoring.foreach.withif
3+
title: Converting foreach with if
4+
slug: learn/refactoring-to-functional-style/foreachwithif
5+
type: tutorial-group
6+
group: refactoring-to-functional-style
7+
layout: learn/tutorial-group.html
8+
subheader_select: tutorials
9+
main_css_id: learn
10+
toc:
11+
- Iterating with foreach {foreach}
12+
- From Imperative to Functional Style {imperativetofunctional}
13+
- Picking elements with if {picking}
14+
- Mappings {mappings}
15+
description: "Converting Imperative Iteration using foreach with if to Functional Style."
16+
last_update: 2023-07-06
17+
author: ["VenkatSubramaniam"]
18+
---
19+
20+
<a id="foreach">&nbsp;</a>
21+
## Iterating with foreach
22+
23+
In the previous articles in this series we looked at converting loops written in the imperative style to the functional style. In this article we'll see how to convert an imperative style iteration using `foreach` to the functional style. In addition, we'll also see how to pick select elements using `if` transforms to the functional style.
24+
25+
Java 5 introduced the very popular `foreach` syntax. For example, to iterate over a collection of `String`s representing names, we'd write something like `for(String name: names)`. Under the hood, the `foreach` is converted, at the bytecode level, to use an `Iterator`&mdash;while the iterator tells us there is another element, fetch the next element for processing. In other words, the `foreach` is a nice concise syntax sugar for iteration with a `while` loop over the elements provided by an `Iterator`. We can convert a `foreach` into the functional style quite easily. Let's see how.
26+
27+
<a id="imperativetofunctional">&nbsp;</a>
28+
## From Imperative to Functional Style
29+
30+
Here's an example of iteration, using the `foreach`, over a collection of names:
31+
32+
```java
33+
List<String> names = List.of("Jack", "Paula", "Kate", "Peter");
34+
35+
for(String name: names) {
36+
System.out.println(name);
37+
}
38+
```
39+
40+
Each step through the iteration, the `name` variable is bound to a new value, as the iteration advances from one element to the next in the given collection. Converting the imperative style `foreach` to the functional style is a straight up use of the `forEach` internal iterator method. It is called an internal iterator because the advancing to the next element is handled internally and automatically instead of externally or explicitly.
41+
42+
Let's refactor the loop to use functional style.
43+
44+
```java
45+
List<String> names = List.of("Jack", "Paula", "Kate", "Peter");
46+
47+
names.forEach(name -> System.out.println(name));
48+
```
49+
50+
That was pretty straightforward, the `for` loop turned into a call to the `forEach()` method on the collection. Each step through the iteration, the lambda provided to the `forEach()` as an argument is invoked with the next element in the collection.
51+
52+
A slightly variation of this iteration, using `stream()`, is shown next.
53+
54+
```java
55+
List<String> names = List.of("Jack", "Paula", "Kate", "Peter");
56+
57+
names.stream()
58+
.forEach(name -> System.out.println(name));
59+
```
60+
The `forEach()` method is available both on a `Collection<T>` and on a `Stream<T>`. Functions like `filter()`, which we'll use soon, are available only on a `Stream<T>` and not on the `Collection`. This is by design in order to provide efficiency when multiple intermediate operations may precede the terminal operation like `forEach()`, `findFirst()`, etc.
61+
62+
<a id="picking">&nbsp;</a>
63+
## Picking select elements with if
64+
65+
Suppose, in the middle of the iteration, we want to pick some values from the collection based on some condition. For example, what if we want to print only names of length 4? In the imperative style we could do the following:
66+
67+
```java
68+
List<String> names = List.of("Jack", "Paula", "Kate", "Peter");
69+
70+
for(String name: names) {
71+
if(name.length() == 4) {
72+
System.out.println(name);
73+
}
74+
}
75+
```
76+
77+
For the functional style, the `filter` method of `Stream` becomes a direct replacement of the imperative style `if`. The `filter` method will allow an element in the collection to pass through to the next stage in the functional pipeline if the predicate, passed in as a lambda, to the `filter()` method evaluates to `true`; otherwise, the value is discarded from further processing.
78+
79+
Let's conver the previous code to functional style:
80+
81+
```java
82+
List<String> names = List.of("Jack", "Paula", "Kate", "Peter");
83+
84+
names.stream()
85+
.filter(name -> name.length() == 4)
86+
.forEach(name -> System.out.println(name));
87+
```
88+
89+
The `filter()` method acts like a gate, it opens to let some elements pass through and closes to reject or discard some elements, as the iteration moves forward.
90+
91+
We saw in the previous articles the functional style equivalent for the traditional `for` loops. In this article we saw how the imperative style `foreach` of Java 5 transforms into an elegant syntax in the functional style. Furthermore, the `if` condition within a loop of the imperative style translates to a call to the `filter()` method of the `Stream` API.
92+
93+
<a id="mappings">&nbsp;</a>
94+
## Mappings
95+
96+
Anywhere you see a `foreach` loop, use the `forEach()` method directly on the collection. If the body of the `foreach` has a `if` statement to selectively pick some value, then use the `stream()` API with the call to the `filter()` method.
97+

0 commit comments

Comments
 (0)