dtonhofer
Functional Programming in Java, Second Edition: Functional Programming in Java, Second Edition: JUnit code improvements for Chapter 11, pages 192 ff “Refactoring File Processing”
In this code:
- We actually create the (temporary) file we want to read and delete it again at the end.
- Default charsets for reading text files are the work of the devil, we set UTF-8 explicitly.
- The files need to be properly closed with try-with-resources, this also applies to the stream approach.
- A “long” count as return value seems excessive, dropping to int.
package chapter11;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class FileProcessingTest {
private static File actualFile;
private final static Charset charset = StandardCharsets.UTF_8;
// Creates a file "/tmp/WordCount13982583023783245787.java" for example
@BeforeAll
static void createTmpFile() throws IOException {
actualFile = File.createTempFile("WordCount", ".java");
try (FileWriter writer = new FileWriter(actualFile, charset)) {
writer.write("package foo;\n");
writer.write("public class X {\n");
writer.write("}\n");
writer.write("public class Y {\n");
writer.write("}\n");
}
}
@AfterAll
static void deleteTmpFile() throws IOException {
// or one could have installed a handler with deleteOnExit()
actualFile.delete();
}
interface WordCount {
int countInFile(String word, File file) throws IOException;
}
// https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/io/FileReader.html
// https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/io/BufferedReader.html
static class WordCountBefore implements WordCount {
public int countInFile(final String searchWord, final File file) throws IOException {
int count = 0;
// Use try-with-resources / automatic resource management to clean up.
// Specify the charset, "default chartset" is the devil's work!
try (final var bufferedReader = new BufferedReader(new FileReader(file, charset))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
final String[] words = line.split(" ");
for (String word : words) {
if (word.equals(searchWord)) {
count++;
}
}
}
return count;
}
}
}
// https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/nio/file/Files.html
static class WordCountAfter implements WordCount {
// The Files.lines() call may throw IOException.
// Additionally, the count() this yields a "long", so we need to cast to fit the interface.
// We still must use try-with-resources to close the file.
public int countInFile(final String searchWord, final File file) throws IOException {
try (final Stream<String> stream = Files.lines(file.toPath(), charset)) {
return (int) stream
.flatMap(line -> Stream.of(line.split(" ")))
.filter(word -> word.equals(searchWord))
.count();
}
}
}
private static void commonFileProcessingTests(final WordCount wordCount, File file) {
assertAll(
() -> assertEquals(2, wordCount.countInFile("public", file)),
() -> assertEquals(1, wordCount.countInFile("package", file)));
}
@Test
void fileProcessingBefore() {
commonFileProcessingTests(new WordCountBefore(), actualFile);
}
@Test
void fileProcessingAfter() {
commonFileProcessingTests(new WordCountAfter(), actualFile);
}
}
Popular Pragmatic Bookshelf topics
In Chapter 3, the source for index introduces Config on page 31, followed by more code including tests; Config isn’t introduced until pag...
New
Running the examples in chapter 5 c under pytest 5.4.1 causes an AttributeError: ‘module’ object has no attribute ‘config’.
In particula...
New
The following is cross-posted from the original Ray Tracer Challenge forum, from a post by garfieldnate. I’m cross-posting it so that the...
New
Hi Jamis,
I think there’s an issue with a test on chapter 6. I own the ebook, version P1.0 Feb. 2019.
This test doesn’t pass for me:
...
New
Hi,
build fails on:
bracket-lib = “~0.8.1”
when running on Mac Mini M1 Rust version 1.5.0:
Compiling winit v0.22.2
error[E0308]: mi...
New
Hi @venkats,
It has been mentioned in the description of ‘Supervisory Job’ title that 2 things as mentioned below result in the same eff...
New
The markup used to display the uploaded image results in a Phoenix.LiveView.HTMLTokenizer.ParseError error.
lib/pento_web/live/product_l...
New
Hi,
I am getting an error I cannot figure out on my test.
I have what I think is the exact code from the book, other than I changed “us...
New
Hi all,
currently I wonder how the Tailwind colours work (or don’t work).
For example, in app/views/layouts/application.html.erb I have...
New
From page 13:
On Python 3.7, you can install the libraries with pip by running these commands inside a Python venv using Visual Studio ...
New
Other popular topics
Hello Devtalk World!
Please let us know a little about who you are and where you’re from :nerd_face:
New
A thread that every forum needs!
Simply post a link to a track on YouTube (or SoundCloud or Vimeo amongst others!) on a separate line an...
New
Learn from the award-winning programming series that inspired the Elixir language, and go on a step-by-step journey through the most impo...
New
Write Elixir tests that you can be proud of. Dive into Elixir’s test philosophy and gain mastery over the terminology and concepts that u...
New
You might be thinking we should just ask who’s not using VSCode :joy: however there are some new additions in the space that might give V...
New
There’s a whole world of custom keycaps out there that I didn’t know existed!
Check out all of our Keycaps threads here:
https://forum....
New
Do the test and post your score :nerd_face:
:keyboard:
If possible, please add info such as the keyboard you’re using, the layout (Qw...
New
Tailwind CSS is an exciting new CSS framework that allows you to design your site by composing simple utility classes to create complex e...
New
Use WebRTC to build web applications that stream media and data in real time directly from one user to another, all in the browser.
...
New
Node.js v22.14.0 has been released.
Link: Release 2025-02-11, Version 22.14.0 'Jod' (LTS), @aduh95 · nodejs/node · GitHub
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /emacs
- /haskell
- /svelte
- /onivim
- /typescript
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /flutter
- /elm
- /vscode
- /ash
- /html
- /opensuse
- /zig
- /deepseek
- /centos
- /php
- /scala
- /react-native
- /lisp
- /sublime-text
- /textmate
- /nixos
- /debian
- /agda
- /django
- /deno
- /kubuntu
- /arch-linux
- /nodejs
- /revery
- /ubuntu
- /spring
- /manjaro
- /diversity
- /lua
- /julia
- /markdown
- /c









