Java
01 / 03

Core Java

Core Java

OOP Fundamentals

// Encapsulation — private fields, public getters/setters
public class User {
    private String name;
    private String email;
    private int age;

    public User(String name, String email, int age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }

    public String getName() { return name; }
    public void setName(String name) {
        if (name == null || name.isBlank()) throw new IllegalArgumentException("Name required");
        this.name = name;
    }

    @Override
    public String toString() {
        return String.format("User{name=%s, email=%s}", name, email);
    }
}

// Inheritance
public class Admin extends User {
    private String role;

    public Admin(String name, String email, String role) {
        super(name, email, 0);
        this.role = role;
    }

    @Override
    public String toString() {
        return super.toString() + String.format(", role=%s", role);
    }
}

// Interfaces (multiple allowed)
public interface Serializable { String serialize(); }
public interface Printable { void print(); }

public class Document implements Serializable, Printable {
    @Override
    public String serialize() { return "{...}"; }

    @Override
    public void print() { System.out.println(serialize()); }
}

// Abstract class
public abstract class Shape {
    abstract double area();
    abstract double perimeter();

    public String describe() {
        return String.format("Area: %.2f, Perimeter: %.2f", area(), perimeter());
    }
}

public class Circle extends Shape {
    private double radius;
    public Circle(double radius) { this.radius = radius; }

    @Override
    double area() { return Math.PI * radius * radius; }

    @Override
    double perimeter() { return 2 * Math.PI * radius; }
}

Collections & Generics

import java.util.*;
import java.util.stream.*;

// List
List<String> list = new ArrayList<>();
list.add("Alice");
list.addAll(Arrays.asList("Bob", "Carol"));
List<String> immutable = List.of("a", "b", "c");

// Map
Map<String, Integer> map = new HashMap<>();
map.put("alice", 1);
map.getOrDefault("bob", 0);
map.putIfAbsent("carol", 3);

// LinkedHashMap preserves insertion order
// TreeMap sorts by key
// Concurrent: ConcurrentHashMap

// Set
Set<String> set = new HashSet<>(Arrays.asList("a", "b", "c"));
Set<String> sorted = new TreeSet<>(set);

// Generics
public class Pair<A, B> {
    private final A first;
    private final B second;

    public Pair(A first, B second) {
        this.first = first;
        this.second = second;
    }
    public A getFirst() { return first; }
    public B getSecond() { return second; }
}

// Bounded wildcards
public double sumList(List<? extends Number> list) {
    return list.stream().mapToDouble(Number::doubleValue).sum();
}

// Streams API
List<String> names = List.of("Alice", "Bob", "Charlie", "David");

List<String> result = names.stream()
    .filter(n -> n.length() > 3)
    .map(String::toUpperCase)
    .sorted()
    .collect(Collectors.toList());

Map<Integer, List<String>> byLength = names.stream()
    .collect(Collectors.groupingBy(String::length));

Optional<String> first = names.stream()
    .filter(n -> n.startsWith("A"))
    .findFirst();

long count = names.stream().filter(n -> n.length() > 4).count();

Exceptions & Concurrency Basics

// Checked vs unchecked exceptions
// Checked: IOException, SQLException — must declare or catch
// Unchecked: RuntimeException, NullPointerException, IllegalArgumentException

try {
    Files.readString(Path.of("file.txt"));
} catch (IOException e) {
    logger.error("Failed to read file", e);
    throw new AppException("Config read failed", e);
} finally {
    cleanup();
}

// Try-with-resources
try (var conn = dataSource.getConnection();
     var stmt = conn.prepareStatement(sql)) {
    stmt.setString(1, userId);
    var rs = stmt.executeQuery();
    // auto-closed on exit
}

// Custom exception
public class ResourceNotFoundException extends RuntimeException {
    private final String resourceType;
    private final String id;

    public ResourceNotFoundException(String resourceType, String id) {
        super(String.format("%s with id %s not found", resourceType, id));
        this.resourceType = resourceType;
        this.id = id;
    }
}

// Concurrency
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<String> future = executor.submit(() -> fetchData());
String result = future.get(5, TimeUnit.SECONDS);
executor.shutdown();

// CompletableFuture — async chains
CompletableFuture.supplyAsync(() -> fetchUser(id))
    .thenApply(user -> enrichUser(user))
    .thenAccept(user -> cache.put(user.getId(), user))
    .exceptionally(e -> { logger.error("Failed", e); return null; });

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free