Nothing surprising here, just adapting the form to the other examples.
Ah yes, compute()
now returns an immutable list in all cases.
package chapter11; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.IntStream; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; public class NestedLoopTest { record Triple(int a, int b, int c) { public String toString() { return String.format("%d %d %d", a, b, c); } } private static Triple triple(int a, int b, int c) { return new Triple(a, b, c); } interface PythagoreanTriples { List<Triple> compute(int numberOfValues); } // (m² - n², 2 * m * n, m² + n²) is a valid triple because, resolving // (m⁴ + n⁴ - 2 * m² * n²) + (4 * m² * n²) = m⁴ + n⁴ + 2 * m² * n² // assuming m > n private static Triple getTripleEuclidsWay(final int m, final int n) { if (m <= n) { throw new IllegalArgumentException("m <= n"); } final int a = m * m - n * n; final int b = 2 * m * n; final int c = m * m + n * n; return triple(a, b, c); } static class PythagoreanTriplesBefore implements PythagoreanTriples { public List<Triple> compute(int tripleCount) { if (tripleCount == 0) { return List.of(); // unmodifiable } List<Triple> triples = new ArrayList<>(); for (int m = 2; ; m++) { for (int n = 1; n < m; n++) { triples.add(getTripleEuclidsWay(m, n)); if (triples.size() == tripleCount) break; } if (triples.size() == tripleCount) break; } return Collections.unmodifiableList(triples); } } static class PythagoreanTriplesAfter implements PythagoreanTriples { public List<Triple> compute(int tripleCount) { return Stream.iterate(2, e -> e + 1) .flatMap(m -> IntStream.range(1, m).mapToObj(n -> getTripleEuclidsWay(m, n))) .limit(tripleCount) .toList(); } } private static void commonPythagoreanTriplesTests(final PythagoreanTriples pytris) { assertAll( () -> assertEquals(List.of(), pytris.compute(0)), () -> assertEquals(List.of(triple(3, 4, 5)), pytris.compute(1)), () -> assertEquals( List.of(triple(3, 4, 5), triple(8, 6, 10), triple(5, 12, 13)), pytris.compute(3)), () -> assertEquals( List.of(triple(3, 4, 5), triple(8, 6, 10), triple(5, 12, 13), triple(15, 8, 17), triple(12, 16, 20)), pytris.compute(5)) ); } @Test void pythagoreanTriplesBefore() { commonPythagoreanTriplesTests(new PythagoreanTriplesBefore()); } @Test void pythagoreanTriplesAfter() { commonPythagoreanTriplesTests(new PythagoreanTriplesAfter()); } }