Java ProgramsNumbersPrint Twin Primes

Print Twin Primes in Java

intermediate·  Numbers  ·  Number Theory

Problem

A twin prime pair is two prime numbers that differ by exactly 2 — listing them means finding every such pair within a range, not just checking one candidate pair.

Given an upper limit, list every twin prime pair found up to that limit.

Input
50
Output
(3, 5), (5, 7), (11, 13), (17, 19), (29, 31), (41, 43)

Java Program

Java
public class PrintTwinPrimes { static boolean isPrime(int n) { if (n < 2) return false; for (int i = 2; i * i <= n; i++) { if (n % i == 0) return false; // found a divisor, not prime } return true; } public static void main(String[] args) { int limit = 50; StringBuilder result = new StringBuilder(); for (int i = 2; i <= limit - 2; i++) { if (isPrime(i) && isPrime(i + 2)) { // both i and its neighbor two higher are prime if (result.length() > 0) result.append(", "); result.append("(").append(i).append(", ").append(i + 2).append(")"); } } System.out.println(result); } }

Output

(3, 5), (5, 7), (11, 13), (17, 19), (29, 31), (41, 43)

Core Logic

Trying every number up to the limit as the smaller half of a candidate pair, and checking whether it and its neighbor two higher are both prime, finds every twin prime pair in the range.

How It Works
  1. 1isPrime(n) is a helper method testing divisors only up to √n.
  2. 2The loop tries every i from 2 up to limit - 2, so i + 2 never runs past the limit.
  3. 3isPrime(i) && isPrime(i + 2) checks whether both i and its neighbor two higher are prime.
  4. 4Each matching pair is appended to the result as (i, i + 2), separated by commas.
For a limit of 50, the scan finds six pairs, starting with (3, 5) and ending with (41, 43).
💡

Key Point: The loop only ever needs to reach limit - 2, not limit itself — checking i + 2 beyond the limit would either go out of range of interest or duplicate work already covered.

Complexity
Time Complexity: O(n√n)Space Complexity: O(n)

Why: Each of the n candidates triggers up to two O(√n) primality checks, and the result string can grow to hold every twin prime pair found.

Key Concepts

helper methodfor loopStringBuilder

Approach 2: Java 8

Java
import java.util.stream.Collectors; import java.util.stream.IntStream; public class PrintTwinPrimesStream { static boolean isPrime(int n) { if (n < 2) return false; return IntStream.rangeClosed(2, (int) Math.sqrt(n)).noneMatch(i -> n % i == 0); } public static void main(String[] args) { int limit = 50; // Keeps candidates where both i and i + 2 are prime, then formats each pair String result = IntStream.rangeClosed(2, limit - 2) .filter(i -> isPrime(i) && isPrime(i + 2)) .mapToObj(i -> "(" + i + ", " + (i + 2) + ")") .collect(Collectors.joining(", ")); System.out.println(result); } }

Output

(3, 5), (5, 7), (11, 13), (17, 19), (29, 31), (41, 43)

Core Logic

The same candidate check can filter a stream of numbers directly, then format and join the survivors.

How It Works
  1. 1IntStream.rangeClosed(2, limit - 2) generates every candidate for the smaller half of a pair.
  2. 2.filter(i -> isPrime(i) && isPrime(i + 2)) keeps only the candidates where both i and i + 2 are prime.
  3. 3.mapToObj(i -> "(" + i + ", " + (i + 2) + ")") formats each surviving candidate into its pair notation.
  4. 4.collect(Collectors.joining(", ")) joins all the formatted pairs into the final result.
Filtering the range up to 48 keeps the same six candidates the loop version finds, formatted and joined identically.
💡

Key Point: The filter condition is the exact same two-prime check the loop version uses — streams just change how the range is walked and the results collected.

Complexity
Time Complexity: O(n√n)Space Complexity: O(n)

Why: The stream still runs the same O(√n) primality checks per candidate, and Collectors.joining() builds a result string holding every matching pair.

Key Concepts

StreamIntStream.rangeClosed()filter()

Related Programs