JavaStreamExamples.java
Stream API: filter, map, collect, group
import java.util.*;
import java.util.stream.*;
record Person(String name, int age, String dept) {}
List<Person> people = List.of(
new Person("Alice", 30, "eng"),
new Person("Bob", 25, "hr"),
new Person("Carol", 35, "eng"),
new Person("Dave", 28, "hr")
);
// filter + map + collect
List<String> engNames = people.stream()
.filter(p -> p.dept().equals("eng"))
.sorted(Comparator.comparingInt(Person::age).reversed())
.map(Person::name)
.collect(Collectors.toList());
// [Carol, Alice]
// groupingBy
Map<String, List<Person>> byDept = people.stream()
.collect(Collectors.groupingBy(Person::dept));
// Average age per department
Map<String, Double> avgAge = people.stream()
.collect(Collectors.groupingBy(
Person::dept,
Collectors.averagingInt(Person::age)
));
// Joining with delimiter
String names = people.stream()
.map(Person::name)
.collect(Collectors.joining(", ", "[", "]"));
// [Alice, Bob, Carol, Dave]
// Statistics
IntSummaryStatistics stats = people.stream()
.mapToInt(Person::age)
.summaryStatistics();
System.out.println(stats.getAverage()); // 29.5
JavaOptionalUsage.java
Optional: safe null handling
import java.util.Optional;
Optional<String> maybeName = Optional.of("Alice");
Optional<String> empty = Optional.empty();
Optional<String> nullable = Optional.ofNullable(null); // safe wrapper
// map: transform if present
Optional<Integer> nameLength = maybeName.map(String::length); // Optional[5]
// flatMap: chain optionals
Optional<String> upper = maybeName
.filter(n -> n.length() > 3)
.map(String::toUpperCase); // Optional[ALICE]
// orElse / orElseGet / orElseThrow
String name = empty.orElse("Anonymous");
String computed = empty.orElseGet(() -> computeDefault());
String required = maybeName.orElseThrow(() -> new RuntimeException("Name required"));
// ifPresent / ifPresentOrElse
maybeName.ifPresent(n -> System.out.println("Hello, " + n));
empty.ifPresentOrElse(
n -> System.out.println("Hello " + n),
() -> System.out.println("No name")
);
// or (Java 9): provide alternative Optional
Optional<String> result = empty.or(() -> Optional.of("fallback"));
static String computeDefault() { return "Default"; }
JavaRecordExamples.java
Records and sealed classes (Java 16/17)
// Record: immutable data carrier — generates constructor, getters, equals, hashCode, toString
record Point(double x, double y) {
// Compact constructor: validate without restating fields
Point {
if (Double.isNaN(x) || Double.isNaN(y))
throw new IllegalArgumentException("NaN coordinate");
}
// Custom instance method
double distanceTo(Point other) {
return Math.hypot(x - other.x, y - other.y);
}
// Static factory
static Point origin() { return new Point(0, 0); }
}
Point p1 = new Point(3, 4);
Point p2 = new Point(0, 0);
System.out.println(p1.x()); // 3.0
System.out.println(p1.distanceTo(p2)); // 5.0
System.out.println(p1); // Point[x=3.0, y=4.0]
// Sealed class: restricts which classes can extend it
sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double w, double h) implements Shape {}
record Triangle(double a, double b, double c) implements Shape {}
double area(Shape s) {
return switch (s) { // exhaustive — compiler warns on missing case
case Circle c -> Math.PI * c.radius() * c.radius();
case Rectangle r -> r.w() * r.h();
case Triangle t -> { double sp = (t.a()+t.b()+t.c())/2;
yield Math.sqrt(sp*(sp-t.a())*(sp-t.b())*(sp-t.c())); }
};
}
JavaPatternMatching.java
Pattern matching: instanceof, switch expressions
// instanceof pattern matching (Java 16)
Object obj = "Hello, World!";
// Old way:
// if (obj instanceof String) { String s = (String) obj; ... }
// New way: pattern variable directly available
if (obj instanceof String s && s.length() > 5) {
System.out.println(s.toUpperCase()); // HELLO, WORLD!
}
// Switch expression with pattern matching (Java 21)
static String describe(Object o) {
return switch (o) {
case Integer i when i < 0 -> "negative int: " + i;
case Integer i -> "positive int: " + i;
case String s when s.isBlank() -> "blank string";
case String s -> "string: " + s;
case null -> "null";
default -> "other: " + o.getClass().getSimpleName();
};
}
System.out.println(describe(-5)); // negative int: -5
System.out.println(describe("hello")); // string: hello
System.out.println(describe(null)); // null
JavaCompletableFutureExamples.java
CompletableFuture: async composition
import java.util.concurrent.*;
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> fetchUserId(42)) // runs on ForkJoinPool
.thenApplyAsync(id -> fetchUserData(id)) // transforms result
.thenApply(data -> data.toUpperCase()) // synchronous transform
.exceptionally(ex -> "fallback: " + ex.getMessage()); // error recovery
// Combine two futures
CompletableFuture<String> user = CompletableFuture.supplyAsync(() -> "Alice");
CompletableFuture<Integer> score = CompletableFuture.supplyAsync(() -> 95);
CompletableFuture<String> combined = user.thenCombine(score,
(u, s) -> u + " scored " + s);
System.out.println(combined.get()); // Alice scored 95
// Wait for all
CompletableFuture.allOf(future, combined).join();
// Wait for first
CompletableFuture<String> fastest = CompletableFuture.anyOf(
CompletableFuture.supplyAsync(() -> slowFetch()),
CompletableFuture.supplyAsync(() -> fastFetch())
).thenApply(Object::toString);
static String fetchUserId(int id) { return "USER-" + id; }
static String fetchUserData(String id) { return "data for " + id; }
static String slowFetch() { return "slow"; }
static String fastFetch() { return "fast"; }
JavaVirtualThreads.java
Virtual threads (Java 21)
import java.util.concurrent.*;
// Virtual thread: lightweight, JVM-managed — millions possible
// Ideal for I/O-bound tasks (HTTP, DB queries)
Thread vt = Thread.ofVirtual().start(() -> {
System.out.println("Running in: " + Thread.currentThread());
// Blocking I/O here is fine — thread is parked, carrier thread is freed
});
vt.join();
// ExecutorService with virtual threads
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
// Submits 10,000 tasks — each gets its own virtual thread
List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < 10_000; i++) {
int taskId = i;
futures.add(executor.submit(() -> processTask(taskId)));
}
for (Future<String> f : futures) {
f.get(); // collect results
}
} // executor is AutoCloseable — shuts down on exit
// Structured concurrency (Java 21 preview)
// try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
// Future<String> user = scope.fork(() -> fetchUser(id));
// Future<Integer> score = scope.fork(() -> fetchScore(id));
// scope.join().throwIfFailed();
// System.out.println(user.get() + ": " + score.get());
// }
static String processTask(int id) throws InterruptedException {
Thread.sleep(10); // simulate I/O
return "done-" + id;
}
JavaGenerics.java
Generics: bounded wildcards and PECS
import java.util.*;
// PECS: Producer Extends, Consumer Super
// Use <? extends T> when reading FROM a collection (producer)
static double sumAll(List<? extends Number> list) {
return list.stream().mapToDouble(Number::doubleValue).sum();
}
// Use <? super T> when writing INTO a collection (consumer)
static void fillWithZeros(List<? super Integer> list, int count) {
for (int i = 0; i < count; i++) list.add(0);
}
// Generic method with multiple bounds
static <T extends Comparable<T> & Cloneable> T max(T a, T b) {
return a.compareTo(b) >= 0 ? a : b;
}
// Generic class
class Pair<A, B> {
private final A first;
private final B second;
Pair(A first, B second) { this.first = first; this.second = second; }
A first() { return first; }
B second() { return second; }
// Swap — returns different parameterisation
Pair<B, A> swap() { return new Pair<>(second, first); }
@Override public String toString() { return "(" + first + ", " + second + ")"; }
}
Pair<String, Integer> p = new Pair<>("hello", 42);
System.out.println(p.swap()); // (42, hello)
JavaFunctionalPatterns.java
Functional interfaces and method references
import java.util.function.*;
// Core functional interfaces: Function, Predicate, Supplier, Consumer, BiFunction
Function<String, Integer> strLen = String::length; // method reference
Function<Integer, String> numStr = Object::toString;
Function<String, String> pipeline = strLen.andThen(numStr); // compose
Predicate<String> longWord = s -> s.length() > 5;
Predicate<String> startsA = s -> s.startsWith("A");
Predicate<String> both = longWord.and(startsA);
Predicate<String> either = longWord.or(startsA);
Predicate<String> notLong = longWord.negate();
System.out.println(both.test("Algorithm")); // true
// BiFunction
BiFunction<String, Integer, String> repeat = (s, n) -> s.repeat(n);
System.out.println(repeat.apply("ab", 3)); // ababab
// Supplier: deferred computation
Supplier<List<String>> listFactory = ArrayList::new;
List<String> list = listFactory.get();
// Consumer
Consumer<String> print = System.out::println;
Consumer<String> log = s -> System.err.println("[LOG] " + s);
print.andThen(log).accept("hello"); // prints and logs
JavaCollectionsModern.java
Modern collections: List.of, Map.of, copyOf
import java.util.*;
// Immutable collections (Java 9+) — cannot add/remove/set
List<String> immutableList = List.of("a", "b", "c");
Set<Integer> immutableSet = Set.of(1, 2, 3);
Map<String, Integer> immutableMap = Map.of(
"one", 1,
"two", 2,
"three", 3
);
// immutableList.add("d"); // throws UnsupportedOperationException
// Map.copyOf / List.copyOf: defensive copy of mutable collection
List<String> mutable = new ArrayList<>(List.of("a", "b"));
List<String> safe = List.copyOf(mutable); // immutable snapshot
// Map.entry and Map.ofEntries for more than 10 entries
Map<String, Integer> big = Map.ofEntries(
Map.entry("a", 1),
Map.entry("b", 2)
// ... up to any number
);
// getOrDefault, computeIfAbsent, merge
Map<String, List<String>> groups = new HashMap<>();
String word = "apple";
groups.computeIfAbsent(String.valueOf(word.charAt(0)), k -> new ArrayList<>())
.add(word);
// merge: combine existing and new value
Map<String, Integer> freq = new HashMap<>();
for (String w : List.of("a", "b", "a")) {
freq.merge(w, 1, Integer::sum); // increment or set to 1
}
System.out.println(freq); // {a=2, b=1}
JavaTryWithResources.java
Try-with-resources and AutoCloseable
import java.io.*;
import java.nio.file.*;
// try-with-resources: closes resources automatically (even on exception)
// Any AutoCloseable works: files, connections, streams, locks
// Read a file safely
static String readFile(Path path) throws IOException {
try (BufferedReader reader = Files.newBufferedReader(path)) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
} // reader.close() called here — even if an exception was thrown
}
// Multiple resources in one try — closed in reverse order
static void copyFile(Path src, Path dst) throws IOException {
try (InputStream in = Files.newInputStream(src);
OutputStream out = Files.newOutputStream(dst)) {
in.transferTo(out);
} // out closed first, then in
}
// Custom AutoCloseable
class ManagedConnection implements AutoCloseable {
ManagedConnection(String url) { System.out.println("Connected to " + url); }
void query(String sql) { System.out.println("Executing: " + sql); }
@Override public void close() { System.out.println("Connection closed"); }
}
try (var conn = new ManagedConnection("db:5432")) {
conn.query("SELECT 1");
} // "Connection closed" always printed
JavaTextBlocks.java
Text blocks and string methods (Java 15+)
// Text block: multiline string, no escaping needed
String json = """
{
"name": "Alice",
"age": 30,
"active": true
}
""";
// Indentation relative to the closing """ is stripped automatically
String html = """
<div class="user">
<h2>%s</h2>
</div>
""".formatted("Alice");
String sql = """
SELECT u.name, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.active = true
GROUP BY u.name
ORDER BY order_count DESC
""";
// New String methods (Java 11-15)
" hello ".strip(); // "hello" (Unicode-aware trim)
"".isBlank(); // true
"hello\nworld\n".lines() // Stream<String>: ["hello", "world"]
.count(); // 2
"abc".repeat(3); // "abcabcabc"
"hello".indent(4); // " hello\n"
JavaConcurrentPatterns.java
Concurrent collections and atomic operations
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
// AtomicInteger: thread-safe counter without synchronized
AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet(); // atomic increment
counter.compareAndSet(1, 2); // CAS: set to 2 only if current is 1
// ConcurrentHashMap: thread-safe map
ConcurrentHashMap<String, AtomicLong> freq = new ConcurrentHashMap<>();
String word = "hello";
freq.computeIfAbsent(word, k -> new AtomicLong(0)).incrementAndGet();
// BlockingQueue: producer-consumer pattern
BlockingQueue<String> queue = new LinkedBlockingQueue<>(100);
// Producer
Thread producer = Thread.ofVirtual().start(() -> {
try {
queue.put("task1"); // blocks if queue full
queue.put("task2");
} catch (InterruptedException e) { Thread.currentThread().interrupt(); }
});
// Consumer
Thread consumer = Thread.ofVirtual().start(() -> {
try {
String task = queue.take(); // blocks until item available
System.out.println("Processing: " + task);
} catch (InterruptedException e) { Thread.currentThread().interrupt(); }
});
JavaBuilderPattern.java
Builder pattern for complex object construction
// Builder: construct objects with many optional parameters clearly
class HttpRequest {
private final String url;
private final String method;
private final Map<String, String> headers;
private final String body;
private final int timeoutMs;
private HttpRequest(Builder b) {
this.url = Objects.requireNonNull(b.url, "url required");
this.method = b.method;
this.headers = Map.copyOf(b.headers);
this.body = b.body;
this.timeoutMs = b.timeoutMs;
}
static Builder builder(String url) { return new Builder(url); }
static class Builder {
private final String url;
private String method = "GET";
private final Map<String, String> headers = new HashMap<>();
private String body;
private int timeoutMs = 5000;
Builder(String url) { this.url = url; }
Builder method(String m) { this.method = m; return this; }
Builder header(String k, String v) { headers.put(k, v); return this; }
Builder body(String b) { this.body = b; return this; }
Builder timeoutMs(int ms) { this.timeoutMs = ms; return this; }
HttpRequest build() { return new HttpRequest(this); }
}
}
var req = HttpRequest.builder("https://api.example.com/users")
.method("POST")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer token123")
.body("{\"name\":\"Alice\"}")
.timeoutMs(10_000)
.build();
Java reference — Java overview · Learn Java
Everything Java in one place — learning paths, reference, playground, and more.
Java Hub →