
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

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

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

Hi! I know not the intentions behind this narrative when called, on page XI:
mount() |> handle_event() |> render()
but the correc...
New

In case this helps anyone, I’ve had issues setting up the rails source code. Here were the solutions:
In Gemfile, change
gem 'rails'
t...
New

A Common-Sense Guide to Data Structures and Algorithms, Second Edition by Jay Wengrow @jaywengrow
Hi,
I have the paperback version of t...
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

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

Getting an error when installing the dependencies at the start of this chapter:
could not compile dependency :exla, "mix compile" failed...
New
Other popular topics

Please tell us what is your preferred monitor setup for programming(not gaming) and why you have chosen it.
Does your monitor have eye p...
New

I know that -t flag is used along with -i flag for getting an interactive shell. But I cannot digest what the man page for docker run com...
New

Not sure if following fits exactly this thread, or if we should have a hobby thread…
For many years I’m designing and building model air...
New

In case anyone else is wondering why Ruby 3 doesn’t show when you do asdf list-all ruby :man_facepalming: do this first:
asdf plugin-upd...
New

Oh just spent so much time on this to discover now that RancherOS is in end of life but Rancher is refusing to mark the Github repo as su...
New

Build highly interactive applications without ever leaving Elixir, the way the experts do. Let LiveView take care of performance, scalabi...
New

A few weeks ago I started using Warp a terminal written in rust. Though in it’s current state of development there are a few caveats (tab...
New

This is going to be a long an frequently posted thread.
While talking to a friend of mine who has taken data structure and algorithm cou...
New

Build efficient applications that exploit the unique benefits of a pure functional language, learning from an engineer who uses Haskell t...
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
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /rails
- /js
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /emacs
- /haskell
- /java
- /onivim
- /typescript
- /svelte
- /crystal
- /kotlin
- /c-plus-plus
- /tailwind
- /gleam
- /react
- /ocaml
- /elm
- /flutter
- /vscode
- /ash
- /opensuse
- /html
- /centos
- /php
- /deepseek
- /zig
- /scala
- /lisp
- /textmate
- /sublime-text
- /nixos
- /debian
- /react-native
- /agda
- /kubuntu
- /arch-linux
- /revery
- /ubuntu
- /django
- /spring
- /manjaro
- /nodejs
- /diversity
- /lua
- /julia
- /c
- /slackware
- /markdown