Skip to content

Commit 91a9a00

Browse files
authored
Merge pull request #29 from java/refactoring
tutorial 1 on refactoring to functional style
2 parents 1cf7fea + 3e83f8c commit 91a9a00

File tree

8 files changed

+142
-4
lines changed

8 files changed

+142
-4
lines changed

app/data/authors.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,13 @@
2929
description: |
3030
José is a cool guy.
3131
and here's more text.
32-
thanks.
32+
thanks.
33+
34+
- name: Venkat Subramaniam
35+
email: venkats@agiledeveloper.com
36+
photo_url: https://itkonekt.com/media/2019/12/Venkat.png
37+
github: venkats
38+
twitter: venkat_s
39+
website: https://agiledeveloper.com/
40+
description: |
41+
Venkat Placeholder.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
id: refactoring
3+
title: "Refactoring from the Imperative to the Functional Style"
4+
slug: learn/refactoring-to-functional-style
5+
type: tutorial
6+
category: language
7+
category_order: 3
8+
group: refactoring-to-functional-style
9+
layout: learn/tutorial-group-top.html
10+
subheader_select: tutorials
11+
main_css_id: learn
12+
description: "Learning to change code from the Imperative to the Functional Style."
13+
author: ["VenkatSubramaniam"]
14+
---
15+
16+
This part of the tutorial helps you to learn the functional style equivalent of the imperative style code we often find. As you move forward in your projects, wherever it makes sense, you can change imperative style code to functional style code using the mappings you learn in this tutorial.
17+
18+
In this series we cover the following conversions from the imperative to the functional style:
19+
20+
| Tutorial |Imperative Style | Functional Style Equivalent |
21+
|------------------------------------------------------|-----------------|------------------------------|
22+
| [Converting Simple Loops](id:refactoring.simple.loops) | `for()` | `range()` or `rangeClosed()` |
23+
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
id: refactoring.simple.loops
3+
title: Converting Simple Loops
4+
slug: learn/refactoring-to-functional-style/simpleloops
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+
- Imperative vs. Functional Styles {styles}
12+
- Simple for Loops {simplefor}
13+
- Mappings {mappings}
14+
description: "Converting Simple Imperative Loops to Functional Style."
15+
last_update: 2023-07-06
16+
author: ["VenkatSubramaniam"]
17+
---
18+
19+
<a id="styles">&nbsp;</a>
20+
## Imperative vs. Functional Styles
21+
22+
The older versions of Java supported the Object-Oriented paradigm mixed with the imperative style of programming. Starting Java 8, you can also mix the functional style of programming in your code. If your code base was started during the Java 7 or earlier times or later by programmers mostly familiar with older versions of Java, it will be filled with the imperative style code.
23+
24+
Imperative style is where we tell what to do and also how to do it. Functional style is declarative in nature, where we tell what to do and delegate the how or the details to the underlying libraries. Imperative style code may be easier to write since most of us are very familiar with it. However, the code becomes verbose, complex, and hard to read. Functional style may be hard at first, mainly because most programmers are less familiar with it. In general, it's easier to read, understand, and change. With practice, it becomes easier to write as well.
25+
26+
In this tutorial series we will take a look at a number of common imperative style code and find a mapping or an equivalent functional style code that we can use instead. As you work with your code based, when you're ready to fix a bug or make an enhancement, you may find it useful to refactor some of the imperative style code to the functional style. You can use this tutorial as a guide to find the imperative to functional style mappings for some common situations.
27+
28+
In this tutorial we'll focus on simple loops.
29+
30+
<a id="simplefor">&nbsp;</a>
31+
## Simple for Loops
32+
33+
Let's start with the traditional for loop where we perform an action for values of an index over a range.
34+
35+
```java
36+
for(int i = 0; i < 5; i++) {
37+
System.out.println(i);
38+
}
39+
```
40+
41+
In the above code, the essence is the range, from `0` to one less than `5`. The ceremony, the noise, from the __how__, is the syntax plus the increment operation on the index variable `i`. We can keep the essence and remove the ceremony by turning the code to the functional style.
42+
43+
If you like to use the functional style to write this `for` loop, you can do quite easily and the clue is in the sentence before the code: __index over a range__. Since we're iterating over a range, the `range` method of `IntStream` is the direct equivalent for this.
44+
45+
```java
46+
import java.util.stream.IntStream;
47+
48+
...
49+
IntStream.range(0, 5)
50+
.forEach(i -> System.out.println(i));
51+
```
52+
53+
You can further make this concise by using a methor reference for the `println` method.
54+
55+
```java
56+
import java.util.stream.IntStream;
57+
58+
...
59+
IntStream.range(0, 5)
60+
.forEach(System.out::println);
61+
```
62+
63+
The functional style code is more concise, easier to read, and the intention is clearer in this version than in the imperative version.
64+
65+
What if your `for` loop runs to include the ending value, like in the following code, you may wonder.
66+
67+
```java
68+
for(int i = 0; i <= 5; i++) {
69+
System.out.println(i);
70+
}
71+
```
72+
73+
The `IntStream` interface has you covered, it has a `rangeClosed` method exactly for this purpose.
74+
75+
```java
76+
import java.util.stream.IntStream;
77+
78+
...
79+
IntStream.rangeClosed(0, 5)
80+
.forEach(System.out::println);
81+
```
82+
83+
The `rangeClosed` method is useful to iterate from the starting value all the way to include the ending value.
84+
85+
Whether you use the `range` method or the `rangeClosed` method, you get a stream of `int` values over which you can use the internal iterator to perform actions. Later in this series we will look at operations beyond `forEach`.
86+
87+
In the previous code examples, the internal iterator removed the burden of iterating from your shoulders. The stream takes care of stepping over the range of values, one at a time. You only have to focus on what to do for each element, as they're provided to you, in the `forEach` method. In our examples, we merely printed the provided value. You can do just about any operation you like, like saving the information to a database, sending it off to a remote service, etc.
88+
89+
Unlike the external iterator provided by the `for` loop, the code that uses the internal iterator is more concise, has less noise, avoids the need to explicitly mutate the index variable, is easier to read, easier to modify, and more pleasant to work with.
90+
91+
Proceed to look for opportunities in your own code base where you see the traditional `for` loop and modify it to using the `IntStream`'s `range` or `rangeClosed` method. Make sure you verify that the code works as expected after the change, preferably by running automated tests that you may already have.
92+
93+
<a id="mappings">&nbsp;</a>
94+
## Mappings
95+
96+
Anywhere you see a simple `for` loop, you can use either the `range` or the `rangeClosed` method of `IntStream`. Use the `range` method if you want to iterate until but not including the ending value. Use the `rangeClosed` to include the ending value as well in your iteration.
97+

app/templates/pages/learn/tutorial-group-top.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919

2020
<h1>{{ file.fm.title_html | safe }}</h1>
2121

22+
{% if file.fm.author %}
23+
{% include "app/templates/partials/_author.html" %}
24+
{% endif %}
25+
2226
<p>{{ contents | safe }}</p>
2327

2428
<br />

app/templates/pages/learn/tutorial-group.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535

3636
<h1>{{ file.fm.title_html | safe }}</h1>
3737

38+
{% if file.fm.author %}
39+
{% include "app/templates/partials/_author.html" %}
40+
{% endif %}
41+
3842
<div class="row">
3943
<div id="content" class="col-9">
4044
<div class="line-numbers">

app/templates/pages/learn/tutorial.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
<h1>{{ file.fm.title_html | safe }}</h1>
2020

2121
{% if file.fm.author %}
22-
This page was contributed by <a href="/author/{{ file.fm.author }}">{{ file.data.authorsMap[file.fm.author].name }}</a> under the <a href="https://oss.oracle.com/licenses/upl/">UPL</a>
23-
<br />
22+
{% include "app/templates/partials/_author.html" %}
2423
{% endif %}
2524

2625
<div class="row">
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
This page was contributed by <a href="/author/{{ file.fm.author }}">{{ file.data.authorsMap[file.fm.author].name }}</a> under the <a href="https://oss.oracle.com/licenses/upl/">UPL</a>
2+
<br />

gulpfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ function pages() {
284284

285285
.pipe(data(function (file) {
286286
if (file.fm.toc) {
287-
const section_name_regex = /^[\s|\w|/|,]+[^{|^\s{]+/;
287+
const section_name_regex = /^[\s\w.,|]+[^{|^\s{]+/;
288288
const anchor_regex = /{([^{|^}]+)}/;
289289
file.fm.toc = file.fm.toc
290290
.map(entry => ({

0 commit comments

Comments
 (0)