dtonhofer
Functional Programming in Java, Second Edition: Code for "Chapter 7, Ininite Collections" in two files
SimpleTimer.java
package chapter7;
import java.util.function.Supplier;
public abstract class SimpleTimer {
public record Result<T>(long duration_ms, T result) {}
public static <T> chapter7.SimpleTimer.Result<T> timeIt(Supplier<T> supplier) {
long start = System.currentTimeMillis();
T result = supplier.get();
long stop = System.currentTimeMillis();
return new Result<T>(stop - start, result);
}
}
BeingLazy_InfiniteCollections.java
package chapter7;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class BeingLazy_InfiniteCollections {
// If CPU cycles are of no importance...
// "a desparate attempt", p.133
public static boolean isPrimeVeryGorilla(final int number) {
return number > 1 &&
IntStream.rangeClosed(2, (int) Math.sqrt(number))
.noneMatch(divisor -> number % divisor == 0);
}
// This doesn't work as it causes an infinite recursion
// "a desparate attempt", p.134, but with different method & parameter names
public static List<Integer> primesUpwardsFrom_notworking(final int number) {
if (isPrimeVeryGorilla(number)) {
List<Integer> morePrimes = primesUpwardsFrom_notworking(number + 1);
morePrimes.add(0, number);
return morePrimes;
} else {
return primesUpwardsFrom_notworking(number + 1);
}
}
// "lazy/fpij/Primes.java", p.135, but with different method & parameter names
private static int firstPrimeAfter(final int number) {
if (isPrimeVeryGorilla(number + 1)) {
return number + 1;
} else {
return firstPrimeAfter(number + 1);
}
}
// "lazy/fpij/Primes.java", p.135, but with different method & parameter names
private static List<Integer> primesUpwardsFrom(final int fromNumber, final int count) {
return Stream.iterate(firstPrimeAfter(fromNumber - 1), BeingLazy_InfiniteCollections::firstPrimeAfter)
.limit(count)
.collect(toList());
}
// Testing primesUpwardsFrom()
// https://en.wikipedia.org/wiki/List_of_prime_numbers
// https://oeis.org/A000040
@Test
public void generatePrimes() {
final var shall = List.of(101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281);
final List<Integer> primesAfter100 = primesUpwardsFrom(100, shall.size());
final String txt = primesAfter100.stream().map(it -> Integer.toString(it)).collect(Collectors.joining(",\n"));
System.out.println(txt);
assertEquals(shall, primesAfter100);
}
// Testing primesUpwardsFrom()
// Similar to "lazy/fpij/Primes.java" on p.136
@Test
public void runBookPrimes() {
List<Integer> l1 = primesUpwardsFrom(1, 10);
List<Integer> l2 = primesUpwardsFrom(100, 5);
assertEquals(List.of(2, 3, 5, 7, 11, 13, 17, 19, 23, 29), l1);
assertEquals(List.of(101, 103, 107, 109, 113), l2);
System.out.println("10 primes from 1: " + l1);
System.out.println("5 primes from 100: " + l2);
}
// It's quite slow!
@Test
void runBookPrimesWithTimer() {
final int limit = 1_000_000;
// not an actual test, just printout
final SimpleTimer.Result<List<Integer>> stRes =
SimpleTimer.timeIt(
() -> primesUpwardsFrom(2, limit)
);
final List<Integer> result = stRes.result();
final String range = (result.isEmpty()) ? "" : "in range [" + result.get(0) + "," + result.get(result.size() - 1) + "] ";
System.out.println("Using book code: finding " + result.size() + " primes " + range + "took " + stRes.duration_ms() + " ms");
}
}
Popular Pragmatic Bookshelf topics
I thought that there might be interest in using the book with Rails 6.1 and Ruby 2.7.2. I’ll note what I needed to do differently here.
...
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
The generated iex result below should list products instead of product for the metadata. (page 67)
iex> product = %Product{}
%Pento....
New
Running mix deps.get in the sensor_hub directory fails with the following error:
** (Mix) No SSH public keys found in ~/.ssh. An ssh aut...
New
“The ProductLive.Index template calls a helper function, live_component/3, that in turn calls on the modal component. ”
Excerpt From: Br...
New
Is the book’s epub format available to read on Google Play Books?
New
Is there any place where we can discuss the solutions to some of the exercises? I can figure most of them out, but am having trouble with...
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
Hello faithful readers! If you have tried to follow along in the book, you are asked to start up the dev environment via dx/build and ar...
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
What chair do you have while working… and why?
Is there a ‘best’ type of chair or working position for developers?
New
@AstonJ prompted me to open this topic after I mentioned in the lockdown thread how I started to do a lot more for my fitness.
https://f...
New
New
I’m thinking of buying a monitor that I can rotate to use as a vertical monitor?
Also, I want to know if someone is using it for program...
New
Curious to know which languages and frameworks you’re all thinking about learning next :upside_down_face:
Perhaps if there’s enough peop...
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
Build efficient applications that exploit the unique benefits of a pure functional language, learning from an engineer who uses Haskell t...
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
There appears to have been an update that has changed the terminology for what has previously been known as the Taskbar Overflow - this h...
New
Jan | Rethink the Computer.
Jan turns your computer into an AI machine by running LLMs locally on your computer. It’s a privacy-focus, l...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /ruby
- /wasm
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /clojure
- /emacs
- /java
- /haskell
- /svelte
- /onivim
- /typescript
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /elm
- /flutter
- /vscode
- /ash
- /html
- /opensuse
- /zig
- /centos
- /deepseek
- /php
- /scala
- /react-native
- /sublime-text
- /lisp
- /textmate
- /debian
- /nixos
- /agda
- /django
- /kubuntu
- /deno
- /arch-linux
- /nodejs
- /ubuntu
- /revery
- /manjaro
- /spring
- /diversity
- /lua
- /markdown
- /julia
- /slackware








