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
Some minor things in the paper edition that says “3 2020” on the title page verso, not mentioned in the book’s errata online:
p. 186 But...
New
Title: Hands-On Rust (Chap 8 (Adding a Heads Up Display)
It looks like
.with_simple_console_no_bg(SCREEN_WIDTH*2, SCREEN_HEIGHT*2...
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
Page 28: It implements io.ReaderAt on the store type.
Sorry if it’s a dumb question but was the io.ReaderAt supposed to be io.ReadAt?
...
New
Title: Web Development with Clojure, Third Edition, vB17.0 (p9)
The create table guestbook syntax suggested doesn’t seem to be accepted ...
New
In general, the book isn’t yet updated for Phoenix version 1.6. On page 18 of the book, the authors indicate that an auto generated of ro...
New
Modern front-end development for Rails, second edition - Struggling to get the first chapter to work
After running /bin/setup, the first error was: The foreman' command exists in these Ruby versions: That was easy to fix: gem install fore...
New
When running the program in chapter 8, “Implementing Combat”, the printout Health before attack was never printed so I assumed something ...
New
@parrt
In the context of Chapter 4.3, the grammar Java.g4, meant to parse Java 6 compilation units, no longer passes ANTLR (currently 4....
New
I got this error when executing the plot files on macOS Ventura 13.0.1 with Python 3.10.8 and matplotlib 3.6.1:
programming_ML/code/03_...
New
Other popular topics
Instantly view the changes you make to an app with stateful hot reload, and define a declarative UI in the same language as the app logic...
New
Algorithms and data structures are much more than abstract concepts. Mastering them enables you to write code that runs faster and more e...
New
New
No chair. I have a standing desk.
This post was split into a dedicated thread from our thread about chairs :slight_smile:
New
Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
New
Hi folks,
I don’t know if I saw this here but, here’s a new programming language, called Roc
Reminds me a bit of Elm and thus Haskell. ...
New
Was just curious to see if any were around, found this one:
I got 51/100:
Not sure if it was meant to buy I am sure at times the b...
New
Author Spotlight
Rebecca Skinner
@RebeccaSkinner
Welcome to our latest author spotlight, where we sit down with Rebecca Skinner, auth...
New
Background
Lately I am in a quest to find a good quality TTS ai generation tool to run locally in order to create audio for some videos I...
New
There’s a GitHub repo at forrestchang/andrej-karpathy-skills that’s sitting at 97.8k stars. It’s a single CLAUDE.md file with four behavi...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /java
- /clojure
- /emacs
- /haskell
- /typescript
- /svelte
- /onivim
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /elm
- /vscode
- /flutter
- /html
- /ash
- /deepseek
- /zig
- /opensuse
- /centos
- /php
- /scala
- /react-native
- /lisp
- /textmate
- /sublime-text
- /nixos
- /debian
- /agda
- /deno
- /django
- /kubuntu
- /arch-linux
- /nodejs
- /ubuntu
- /spring
- /revery
- /manjaro
- /julia
- /lua
- /diversity
- /quarkus
- /markdown









