dtonhofer
Functional Programming in Java, Second Edition: Functional Programming in Java, Second Edition: JUnit code improvements for Chapter 11, pages 189 ff “Refactoring to Rework the Logic”
The usual changes but:
- The “FirstRepeatedLetter.findIn()” has been improved out of the box. In particular returning ‘\0’ is too C-like and smells like “primitive obsession”. We have
null, we should use it. What if the input contains\0as the matching character? - A slightly better code (IMHO) is in
FirstRepeatedLetterBetter.findIn() - The final refactored code returns not null, but
Optional<Character>, which is cleaner. - Again, for testing we use a common interface or a wrapper class to avoid having to duplicate testing code.
package chapter11;
import org.junit.jupiter.api.Test;
import java.util.Optional;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
public class ReworkTheLogicTest {
interface FindLetter {
Character findIn(String word);
}
static class FirstRepeatedLetterBefore implements FindLetter {
public Character findIn(final String word) {
final char[] letters = word.toCharArray();
for (char candidate : letters) {
int count = 0;
for (char letter : letters) {
if (candidate == letter) {
count++;
}
}
if (count > 1) {
return candidate;
}
}
return null;
}
}
static class FirstRepeatedLetterBetter implements FindLetter {
public Character findIn(final String word) {
char[] letters = word.toCharArray();
int i = 0;
Character found = null;
while (i < letters.length && found == null) {
// will letter[i] been seen again?
char maybe = letters[i];
int j = i + 1;
while (j < letters.length && letters[j] != maybe) j++;
if (j < letters.length) {
found = maybe;
} else {
i++;
}
}
return found;
}
}
// Does NOT implement "FindLetter", returns Optional<Character>
static class FirstRepeatedLetterAfter {
public Optional<Character> findIn(final String word) {
return Stream.of(word.split(""))
.filter(letter -> word.lastIndexOf(letter) > word.indexOf(letter))
.findFirst()
.map(letter -> letter.charAt(0));
}
}
static class FirstRepeatedLetterAfterWrapped implements FindLetter {
private final FirstRepeatedLetterAfter finder;
public FirstRepeatedLetterAfterWrapped(FirstRepeatedLetterAfter finder) {
this.finder = finder;
}
public Character findIn(final String word) {
return finder.findIn(word).orElse(null);
}
}
private static void commonFindFirstRepeatingTests(final FindLetter finder) {
assertAll(
() -> assertEquals('l', finder.findIn("hello")),
() -> assertEquals('h', finder.findIn("hellothere")),
() -> assertEquals('a', finder.findIn("magicalguru")),
() -> assertEquals('z', finder.findIn("abcdefghijklmnopqrstuvwxyzz")),
() -> assertNull(finder.findIn("once")),
() -> assertNull(finder.findIn(""))
);
}
@Test
void findFirstRepeatingBefore() {
commonFindFirstRepeatingTests(new FirstRepeatedLetterBefore());
}
@Test
void findFirstRepeatingBetter() {
commonFindFirstRepeatingTests(new FirstRepeatedLetterBetter());
}
@Test
void findFirstRepeatingAfter() {
commonFindFirstRepeatingTests(new FirstRepeatedLetterAfterWrapped(new FirstRepeatedLetterAfter()));
}
}
Popular Pragmatic Bookshelf topics
Working through the steps (checking that the Info,plist matches exactly), run the demo game and what appears is grey but does not fill th...
New
your book suggests to use Image.toByteData() to convert image to bytes, however I get the following error: "the getter ‘toByteData’ isn’t...
New
I can’t setup the Rails source code. This happens in a working directory containing multiple (postgres) Rails apps.
With:
ruby-3.0.0
s...
New
@noelrappin
Running the webpack dev server, I receive the following warning:
ERROR in tsconfig.json
TS18003: No inputs were found in c...
New
I’m running Android Studio “Arctic Fox” 2020.3.1 Patch 2, and I’m embarrassed to admit that I only made it to page 8 before running into ...
New
I’m under the impression that when the reader gets to page 136 (“View Data with the Database Inspector”), the code SHOULD be able to buil...
New
I found an issue in Chapter 7 regarding android:backgroundTint vs app:backgroundTint.
How to replicate:
load chapter-7 from zipfile i...
New
Title: Build a Weather Station with Elixir and Nerves: Problem connecting to Postgres with Grafana on (page 64)
If you follow the defau...
New
@mfazio23
I’m following the indications of the book and arriver ad chapter 10, but the app cannot be compiled due to an error in the Bas...
New
Docker-Machine became part of the Docker Toolbox, which was deprecated in 2020, long after Docker Desktop supported Docker Engine nativel...
New
Other popular topics
Stop developing web apps with yesterday’s tools. Today, developers are increasingly adopting Clojure as a web-development platform. See f...
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
No chair. I have a standing desk.
This post was split into a dedicated thread from our thread about chairs :slight_smile:
New
From finance to artificial intelligence, genetic algorithms are a powerful tool with a wide array of applications. But you don't need an ...
New
We’ve talked about his book briefly here but it is quickly becoming obsolete - so he’s decided to create a series of 7 podcasts, the firs...
New
New
Big O Notation can make your code faster by orders of magnitude. Get the hands-on info you need to master data structures and algorithms ...
New
Will Swifties’ war on AI fakes spark a deepfake porn reckoning?
New
An illustrated guide to understanding and effectively using regular expressions.
Staffan Nöteberg
To effectively use regular expressi...
New
Hair Salon Games for Girls Fun
Girls Hair Saloon game is mainly developed for kids. This game allows users to select virtual avatars to ...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /java
- /clojure
- /typescript
- /emacs
- /haskell
- /svelte
- /onivim
- /kotlin
- /react
- /c-plus-plus
- /crystal
- /tailwind
- /gleam
- /ocaml
- /elm
- /vscode
- /flutter
- /html
- /deepseek
- /ash
- /zig
- /opensuse
- /php
- /centos
- /react-native
- /scala
- /lisp
- /sublime-text
- /textmate
- /nixos
- /debian
- /agda
- /deno
- /django
- /nodejs
- /kubuntu
- /arch-linux
- /ubuntu
- /spring
- /revery
- /manjaro
- /julia
- /quarkus
- /diversity
- /lua
- /laravel









