Java Quick Reference

Complete Java reference โ€” all W3Schools topics in one place, simple & memorable.

Syntax OOP DS & Collections File I/O Threads Generics RegEx Date & Time
โ˜• Java Basics
๐Ÿ”
๐Ÿ”ข
Data Types
Primitives + String
// Integer types
byte   b = 127;          // -128 to 127
short  s = 32000;
int    i = 100;          // most common
long   l = 100L;         // note: L suffix

// Decimal types
float  f = 3.14f;        // note: f suffix
double d = 3.14;         // more precise

// Other
char   c = 'A';
boolean flag = true;
String name = "Java";    // not primitive!
๐Ÿ“ฆ
Variables & Constants
Declaration & assignment
// Declare & assign
int age = 25;
String city = "Mumbai";

// var (Java 10+): type inferred
var name = "Ravi";      // String inferred
var count = 10;        // int inferred

// Constant: use final
final double PI = 3.14159;
// PI = 3; โ† ERROR! Can't reassign

// Multiple on one line
int x = 1, y = 2, z = 3;
๐Ÿ”€
Conditions
if / else / switch / ternary
// if-else
if (age >= 18) {
    System.out.println("Adult");
} else if (age >= 13) {
    System.out.println("Teen");
} else { System.out.println("Child"); }

// Ternary: condition ? yes : no
String result = age >= 18 ? "Adult" : "Minor";

// Switch (classic)
switch (day) {
  case "Mon": System.out.println("Monday"); break;
  default:  System.out.println("Other");
}

// Switch expression (Java 14+)
String type = switch (day) {
  case "Sat", "Sun" -> "Weekend";
  default -> "Weekday";
};
๐Ÿ”
Loops
for / while / do-while / for-each
// Classic for loop
for (int i = 0; i < 5; i++) {
    System.out.println(i); // 0,1,2,3,4
}

// For-each (enhanced) โ€” best for collections
int[] nums = {1,2,3};
for (int n : nums) { System.out.println(n); }

// While loop
int n = 0;
while (n < 3) { n++; }

// Do-while: runs at least ONCE
do {
    System.out.println("runs once");
} while (false);

// break exits loop, continue skips iteration
โšก
Methods
Declaration, return, overload
// Method syntax: returnType name(params)
public static int add(int a, int b) {
    return a + b;
}

// void = returns nothing
public static void greet(String name) {
    System.out.println("Hi, " + name);
}

// Overloading: same name, different params
public static int add(int a, int b, int c) {
    return a + b + c;
}

// Calling
int sum = add(3, 4);  // 7
๐Ÿ”ค
String Methods
Most used string operations
String s = "Hello Java";

s.length();           // 10
s.toUpperCase();      // "HELLO JAVA"
s.toLowerCase();      // "hello java"
s.charAt(0);          // 'H'
s.substring(6);       // "Java"
s.substring(0,5);    // "Hello"
s.contains("Java");  // true
s.replace("Java","World"); // "Hello World"
s.split(" ");         // ["Hello","Java"]
s.trim();              // remove spaces
s.equals("Hello Java");// true (use for compare!)
s.indexOf("J");       // 6
String.format("Hi %s", name); // format
๐Ÿงฎ
Operators
Arithmetic, comparison, logical
// Arithmetic
10 + 3  // 13   10 - 3  // 7
10 * 3  // 30   10 / 3  // 3 (integer!)
10 % 3  // 1 (modulus / remainder)

// Comparison (return boolean)
== != > < >= <=

// Logical
&& // AND: both true
|| // OR: either true
!  // NOT: flip boolean

// Assignment shortcuts
x += 5;  // x = x + 5
x++;     // x = x + 1
x--;     // x = x - 1

// Math class
Math.pow(2,3) // 8.0
Math.sqrt(9) // 3.0
Math.abs(-5) // 5
Math.max(4,9) // 9
๐Ÿ”„
Type Casting
Widening, narrowing, parsing
// Widening (auto, safe): smaller โ†’ bigger
int i = 10;
double d = i;  // 10.0 automatically

// Narrowing (manual): bigger โ†’ smaller
double pi = 3.99;
int n = (int) pi;  // 3 (decimal dropped!)

// String โ†’ number
int age = Integer.parseInt("25");
double price = Double.parseDouble("9.99");

// Number โ†’ String
String s = String.valueOf(42);
String s2 = "" + 42;  // quick trick
๐Ÿ—๏ธ Object-Oriented Programming
๐Ÿ›๏ธ
Class & Object
Blueprint and instance
A class is a blueprint. An object is a real instance of that blueprint with actual values.
// Define a class
public class Car {
    // Fields (attributes)
    String brand;
    int    speed;

    // Constructor
    public Car(String brand, int speed) {
        this.brand = brand;
        this.speed = speed;
    }

    // Method
    public void describe() {
        System.out.println(brand + " at " + speed);
    }
}

// Create objects
Car c1 = new Car("Toyota", 120);
c1.describe(); // Toyota at 120
๐Ÿงฌ
Inheritance
extends, super, override
Child class inherits all fields & methods from parent. Use extends.
class Animal {
    String name;
    public void speak() { System.out.println("..."); }
}

class Dog extends Animal {
    // Override parent method
    @Override
    public void speak() { System.out.println("Woof!"); }
}

class GuideDog extends Dog {
    public void guide() {
        super.speak(); // call parent speak
        System.out.println("Leading...");
    }
}

Dog d = new Dog();
d.name = "Rex";
d.speak(); // Woof!
๐ŸŽญ
Interface & Abstract
implements, abstract class
// Interface: defines WHAT, not HOW
interface Printable {
    void print();            // must implement
    default void preview() { // optional default
        System.out.println("preview");
    }
}

class Document implements Printable {
    public void print() { System.out.println("Printing"); }
}

// Abstract: partial implementation
abstract class Shape {
    abstract double area();  // subclass must implement
    void show() { System.out.println(area()); }
}

class Circle extends Shape {
    double r;
    double area() { return Math.PI * r * r; }
}
๐Ÿ”’
Access Modifiers
public, private, protected
Modifier Same Class Same Package Subclass World
public โœ“ โœ“ โœ“ โœ“
protected โœ“ โœ“ โœ“ โœ—
default โœ“ โœ“ โœ— โœ—
private โœ“ โœ— โœ— โœ—
class Person {
    private   String name;  // only this class
    protected int    age;   // subclasses too
    public    String id;    // everyone
    // Getter/Setter for private
    public String getName() { return name; }
    public void setName(String n) { name = n; }
}
๐Ÿ“Š Arrays
1๏ธโƒฃ
1D Array
Fixed-size list of same type
Array = fixed-size, stores same type, index starts at 0. Size cannot change after creation.
// Declare + initialize
int[] nums = {10, 20, 30, 40};
String[] names = new String[3]; // empty, size 3

// Access element: arrayName[index]
System.out.println(nums[0]);  // 10
System.out.println(nums[3]);  // 40 (last)

// Change value
nums[1] = 99;  // now {10,99,30,40}

// Length
nums.length   // 4 (property, not method!)

// Loop through
for (int n : nums) System.out.println(n);

// Sort
Arrays.sort(nums);  // {10,30,40,99}
2๏ธโƒฃ
2D Array (Matrix)
Table/grid structure
// Declare 2D array [rows][cols]
int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// Access: matrix[row][col]
matrix[0][0]  // 1 (top-left)
matrix[1][2]  // 6
matrix[2][2]  // 9 (bottom-right)

// Change value
matrix[0][1] = 99;

// Loop through 2D
for (int[] row : matrix) {
    for (int val : row) {
        System.out.print(val + " ");
    }
    System.out.println();
}
๐Ÿ› ๏ธ
Arrays Utility
java.util.Arrays methods
import java.util.Arrays;

int[] a = {5,2,8,1};

Arrays.sort(a);              // [1,2,5,8]
Arrays.toString(a);          // "[1, 2, 5, 8]"
Arrays.fill(a, 0);           // [0,0,0,0]
Arrays.copyOf(a, 2);         // [0,0] first 2
Arrays.copyOfRange(a,1,3);   // index 1 to 2
Arrays.binarySearch(a, 5);  // index (sort first!)
Arrays.equals(a, b);         // compare two arrays

// Convert array to List
List<Integer> list = Arrays.asList(1,2,3);
๐Ÿ—๏ธ Data Structures (Built-in)

Click any card to expand full details โ€” declaration, add, remove, access, iterate, and more.

๐Ÿ“š
Stack
LIFO โ€” Last In, First Out
LIFO
โ–ผ
Stack works like a pile of plates ๐Ÿฝ๏ธ โ€” you can only add or remove from the top. Last item added is the first to come out.
๐Ÿ“Œ Declare & Create
import java.util.Stack;
Stack<Integer> stack = new Stack<>();
โž• Add (push)
stack.push(10);
stack.push(20);
stack.push(30);
// Stack: [10, 20, 30] โ† top
โž– Remove (pop)
stack.pop();   // removes & returns 30
stack.pop();   // removes & returns 20
// Stack: [10]
๐Ÿ‘๏ธ Access (peek)
stack.peek();     // see top (no remove)
stack.isEmpty(); // false
stack.size();    // 1
stack.search(10); // position from top
๐Ÿ’ก Use Stack for: undo operations, browser back button, balancing parentheses, recursion simulation.
โš ๏ธ pop() on empty stack throws EmptyStackException. Always check isEmpty() first!
๐Ÿšถ
Queue (LinkedList)
FIFO โ€” First In, First Out
FIFO
โ–ผ
Queue is like a real queue/line ๐Ÿง๐Ÿง๐Ÿง โ€” first person to join is first to leave. Add to back, remove from front.
๐Ÿ“Œ Declare & Create
import java.util.*;
Queue<String> q = new LinkedList<>();
โž• Add (offer/add)
q.offer("Alice");  // safe add
q.offer("Bob");
q.offer("Carol");
// Queue: Alice โ† Bob โ† Carol
โž– Remove (poll)
q.poll();  // removes Alice (front)
q.poll();  // removes Bob
// Queue: Carol
๐Ÿ‘๏ธ Access (peek)
q.peek();    // see front, no remove
q.size();    // 1
q.contains("Carol"); // true
๐Ÿ’ก Use offer() instead of add() โ€” it returns false on failure vs throwing exception. Use poll() vs remove() for same reason.
๐Ÿ”—
LinkedList (as Deque)
Doubly linked โ€” add/remove both ends
Deque
โ–ผ
LinkedList is a chain of nodes ๐Ÿ”— where each node points to next and previous. Can work as both Stack AND Queue.
๐Ÿ“Œ Declare
LinkedList<Integer> ll = new LinkedList<>();
โž• Add anywhere
ll.addFirst(1);  // add to front
ll.addLast(2);   // add to back
ll.add(1, 99);  // add at index 1
โž– Remove
ll.removeFirst(); // remove front
ll.removeLast();  // remove back
ll.remove(0);     // remove at index
๐Ÿ‘๏ธ Access
ll.get(0);      // by index (slow!)
ll.getFirst(); // O(1)
ll.getLast();  // O(1)
ll.set(0, 50); // change at index
โš ๏ธ get(index) is O(n) in LinkedList โ€” it traverses from start. Use ArrayList for random access!
๐ŸŽฏ
PriorityQueue
Always removes the smallest element first
Min-Heap
โ–ผ
PriorityQueue always removes the smallest (or highest priority) element first โ€” regardless of insertion order. Internally uses a heap.
๐Ÿ“Œ Declare
PriorityQueue<Integer> pq = new PriorityQueue<>();
// Max-heap (largest first):
PriorityQueue<Integer> max =
  new PriorityQueue<>(Collections.reverseOrder());
โž• Add
pq.offer(30);
pq.offer(10);
pq.offer(20);
โž– Remove (poll)
pq.poll();  // returns 10 (smallest!)
pq.poll();  // returns 20
pq.poll();  // returns 30
๐Ÿ‘๏ธ Access
pq.peek();    // see min without removing
pq.size();    // count
pq.contains(10); // check exists
๐Ÿ’ก Use PriorityQueue for: Dijkstra's algorithm, scheduling tasks by priority, finding K smallest/largest elements.
๐Ÿ“ฆ Collections Framework

Click to expand each collection โ€” all operations with examples.

๐Ÿ“‹
ArrayList
Dynamic array โ€” ordered, allows duplicates
Most Used
โ–ผ
ArrayList = resizable array. Best for: reading by index. Maintains insertion order. Allows duplicates and null.
๐Ÿ“Œ Declare
import java.util.ArrayList;
ArrayList<String> list = new ArrayList<>();
// With initial data:
ArrayList<Integer> nums =
  new ArrayList<>(List.of(1,2,3));
โž• Add elements
list.add("Apple");       // add to end
list.add(0, "Mango");  // add at index 0
list.addAll(otherList);  // add all from list
โž– Remove elements
list.remove("Apple"); // remove by value
list.remove(0);       // remove at index 0
list.clear();          // remove ALL
โœ๏ธ Change value
list.set(0, "Banana"); // replace index 0
๐Ÿ‘๏ธ Access / Read
list.get(0);           // get by index โ†’ O(1)
list.size();           // count
list.contains("Apple");// boolean
list.indexOf("Apple"); // first index
list.isEmpty();        // boolean
๐Ÿ” Iterate
for (String s : list) System.out.println(s);
list.forEach(s -> System.out.println(s));
Collections.sort(list);  // sort it
๐Ÿ”—
LinkedList (as List)
Doubly linked nodes โ€” fast add/remove at ends
List+Deque
โ–ผ
LinkedList implements both List and Deque. Best for: frequent insert/delete in middle or at ends.
๐Ÿ“Œ Declare
LinkedList<String> ll = new LinkedList<>();
โž• Add
ll.add("A");       // end
ll.addFirst("Z"); // front
ll.addLast("B");  // back
โž– Remove
ll.remove("A");    // by value
ll.removeFirst(); // front โ†’ O(1)
ll.removeLast();  // back โ†’ O(1)
โœ๏ธ Change value
ll.set(0, "X"); // replace at index
๐Ÿ‘๏ธ Access
ll.get(2);      // by index โ†’ O(n)
ll.getFirst(); // O(1)
ll.getLast();  // O(1)
๐Ÿ” Iterate
for (String s : ll) System.out.println(s);
๐Ÿ—บ๏ธ
HashMap
Key-Value pairs โ€” no order, O(1) access
Key-Value
โ–ผ
HashMap stores data as key โ†’ value pairs. Keys are unique. No guaranteed order. Fast lookup O(1) average.
๐Ÿ“Œ Declare
import java.util.HashMap;
HashMap<String, Integer> map =
  new HashMap<>();
โž• Add (put)
map.put("Alice", 90);
map.put("Bob",   85);
map.put("Alice", 95); // overwrites!
โž– Remove
map.remove("Bob");       // by key
map.remove("Alice", 95); // key+value
map.clear();              // remove all
โœ๏ธ Change value
map.put("Alice", 100); // put again
map.replace("Alice", 99);
๐Ÿ‘๏ธ Access
map.get("Alice");          // 95
map.getOrDefault("X", 0); // safe!
map.containsKey("Bob");   // true/false
map.containsValue(85);   // true/false
map.size();
๐Ÿ” Iterate
// Keys
for (String key : map.keySet()) ...
// Values
for (Integer val : map.values()) ...
// Both (best way)
for (var e : map.entrySet())
  System.out.println(e.getKey()+"="+e.getValue());
๐Ÿ’ก Increment counter pattern: map.put(key, map.getOrDefault(key, 0) + 1); โ€” very common in coding!
๐Ÿ—บ๏ธ
LinkedHashMap
HashMap + maintains insertion order
Ordered Map
โ–ผ
Same as HashMap but remembers the order you inserted items. Slightly slower than HashMap due to linked list overhead.
๐Ÿ“Œ Declare
LinkedHashMap<String, Integer> lhm =
  new LinkedHashMap<>();
โž• Add / โœ๏ธ Change
lhm.put("One", 1);
lhm.put("Two", 2);
lhm.put("Three", 3);
lhm.replace("Two", 22);
โž– Remove / ๐Ÿ‘๏ธ Access
lhm.remove("One");
lhm.get("Two"); // 22
// Iterates in insertion order:
// Two=22, Three=3
๐Ÿ’ก Use LinkedHashMap when you need map + order (e.g., LRU cache, processing entries in insertion sequence).
๐ŸŒณ
TreeMap
Sorted Map โ€” keys always sorted
Sorted
โ–ผ
TreeMap keeps keys in sorted (ascending) order always. Based on Red-Black tree. O(log n) for all operations.
๐Ÿ“Œ Declare
TreeMap<String, Integer> tm =
  new TreeMap<>();
// Reverse order:
TreeMap<String,Integer> rev =
  new TreeMap<>(Collections.reverseOrder());
โž• Add / โœ๏ธ Change
tm.put("Banana", 3);
tm.put("Apple",  5);
tm.put("Cherry", 1);
// Stored: Apple, Banana, Cherry
tm.replace("Apple", 10);
โž– Remove / ๐Ÿ‘๏ธ Extra methods
tm.remove("Banana");
tm.firstKey(); // "Apple" (smallest)
tm.lastKey();  // "Cherry" (largest)
tm.floorKey("B");  // "Apple"
tm.ceilingKey("B"); // "Cherry"
tm.headMap("C");   // keys before C
tm.tailMap("B");   // keys from B
๐ŸŽฏ
HashSet
Unique values โ€” no duplicates, no order
No Duplicates
โ–ผ
HashSet stores unique values only. Adding a duplicate is silently ignored. No order. O(1) for add/remove/contains.
๐Ÿ“Œ Declare
import java.util.HashSet;
HashSet<String> set = new HashSet<>();
โž• Add elements
set.add("Apple");  // true
set.add("Mango");  // true
set.add("Apple");  // false! duplicate ignored
// Set: {Apple, Mango}
โž– Remove
set.remove("Apple"); // by value
set.clear();          // remove all
๐Ÿ‘๏ธ Access / Check
set.contains("Mango"); // true โ†’ O(1)
set.size();
set.isEmpty();
// No get(index)! No order!
๐Ÿ” Iterate & Set Ops
for (String s : set) System.out.println(s);

// Set operations
setA.addAll(setB);      // Union
setA.retainAll(setB);  // Intersection
setA.removeAll(setB);  // Difference
๐Ÿ’ก Best use: removing duplicates from a list โ†’ new HashSet<>(list) instantly removes all duplicates!
๐ŸŒฒ
TreeSet
Sorted unique values โ€” always ascending
Sorted Unique
โ–ผ
TreeSet = HashSet + automatically sorted in ascending order. No duplicates. Based on TreeMap internally.
๐Ÿ“Œ Declare
TreeSet<Integer> ts = new TreeSet<>();
ts.add(5); ts.add(1); ts.add(3);
// Stored: {1, 3, 5} โ€” auto sorted!
๐Ÿ‘๏ธ Special Access
ts.first();       // 1 (min)
ts.last();        // 5 (max)
ts.floor(4);     // 3 (โ‰ค4)
ts.ceiling(4);   // 5 (โ‰ฅ4)
ts.headSet(4);   // {1,3} (< 4)
ts.tailSet(3);   // {3,5} (โ‰ฅ 3)
โž– Remove
ts.remove(3);   // {1, 5}
ts.pollFirst(); // removes & returns 1
ts.pollLast();  // removes & returns 5
โšก Compare All โ€” At a Glance
๐Ÿ“Š
List Implementations
When to use which?
Feature ArrayList LinkedList Vector
Access by index O(1) โœ“ Fast O(n) โœ— Slow O(1) โœ“
Add/remove at end O(1) amortized O(1) โœ“ O(1)
Add/remove at middle O(n) โœ— O(1) โœ“ O(n)
Memory Less (array) More (node+pointer) Less
Thread safe โœ— No โœ— No โœ“ Yes (legacy)
Allows null โœ“ โœ“ โœ“
Best use Read heavy Insert/Delete heavy Legacy (avoid)
๐Ÿ—บ๏ธ
Map Implementations
Feature HashMap LinkedHashMap TreeMap Hashtable
Order โŒ None โœ… Insertion โœ… Sorted (key) โŒ None
get/put speed O(1) avg O(1) avg O(log n) O(1) avg
Null key โœ… 1 allowed โœ… 1 allowed โŒ No โŒ No
Null value โœ… Yes โœ… Yes โœ… Yes โŒ No
Thread safe โŒ No โŒ No โŒ No โœ… Yes (legacy)
Use when General use Order matters Sorted keys needed Legacy (avoid)
๐ŸŽฏ
Set Implementations
Feature HashSet LinkedHashSet TreeSet
Order โŒ None โœ… Insertion order โœ… Sorted (asc)
Speed (add/contains) O(1) avg O(1) avg O(log n)
Allows null โœ… One null โœ… One null โŒ No
Duplicates โŒ No โŒ No โŒ No
Best use Fast lookup/dedup Unique + order Sorted unique
๐Ÿ—๏ธ
Stack vs Queue vs Deque vs PriorityQueue
Feature Stack Queue Deque (LinkedList) PriorityQueue
Order LIFO FIFO Both ends Priority (min)
Add push() offer() addFirst/Last() offer()
Remove pop() poll() removeFirst/Last() poll()
Peek peek() peek() peekFirst/Last() peek()
Thread safe โœ… Yes (legacy) โŒ No โŒ No โŒ No
Use for Undo, DFS BFS, tasks Palindrome, sliding window Scheduling, Dijkstra
โš ๏ธ Exception Handling
๐Ÿšจ
try-catch-finally
try {
    int result = 10 / 0;      // throws!
} catch (ArithmeticException e) {
    System.out.println("Error: " + e.getMessage());
} catch (Exception e) {       // catch-all
    e.printStackTrace();
} finally {
    System.out.println("Always runs!");
    // close resources here
}

// Multi-catch (Java 7+)
catch (IOException | SQLException e) { ... }

// Try-with-resources (auto-close)
try (FileReader fr = new FileReader("f.txt")) {
    // fr auto-closed when done
}
๐Ÿงจ
throw & Custom Exceptions
// throws declaration
public void setAge(int age) throws Exception {
    if (age < 0) throw new Exception("Bad age");
    this.age = age;
}

// Custom exception
class InvalidAgeException extends RuntimeException {
    public InvalidAgeException(String msg) {
        super(msg);
    }
}
// Use it
throw new InvalidAgeException("Age must be >= 0");

// Common exceptions to know:
// NullPointerException, ArrayIndexOutOfBoundsException
// ClassCastException, NumberFormatException
// StackOverflowError, OutOfMemoryError
๐ŸŒŠ Streams & Lambdas (Java 8+)
ฮป
Lambda Expressions
// Old way (anonymous class)
Runnable r = new Runnable() {
    public void run() { System.out.println("Hi"); }
};

// Lambda way: (params) -> body
Runnable r2 = () -> System.out.println("Hi");

// With parameters
Comparator<Integer> cmp = (a, b) -> a - b;

// Method reference (even shorter)
list.forEach(System.out::println);
๐ŸŒŠ
Stream Operations
List<Integer> nums = List.of(1,2,3,4,5,6);

// filter โ†’ map โ†’ collect
List<Integer> evens = nums.stream()
    .filter(n -> n % 2 == 0)  // keep even
    .map(n -> n * 10)          // multiply
    .collect(Collectors.toList());
// [20, 40, 60]

// reduce โ†’ single value
int sum = nums.stream().reduce(0, Integer::sum);

// sorted, distinct, count
nums.stream().sorted().distinct().count();

// anyMatch, allMatch, noneMatch
nums.stream().anyMatch(n -> n > 4); // true

// findFirst
nums.stream().filter(n->n>3).findFirst(); // Optional[4]
๐Ÿ“ฆ
Optional (avoid null)
// Wrap value that might be null
Optional<String> opt = Optional.of("Hello");
Optional<String> empty = Optional.empty();

opt.isPresent();          // true
opt.get();                // "Hello"
opt.orElse("default");   // value or default
opt.orElseGet(() -> ...); // lazy default
opt.map(String::toUpperCase); // transform
opt.ifPresent(s -> System.out.println(s));
๐Ÿงฉ
Functional Interfaces
// Predicate: T โ†’ boolean
Predicate<String> notEmpty = s -> !s.isEmpty();

// Function: T โ†’ R
Function<String, Integer> len = s -> s.length();

// Consumer: T โ†’ void
Consumer<String> print = System.out::println;

// Supplier: () โ†’ T
Supplier<String> hello = () -> "Hello!";

// BiFunction: (T,U) โ†’ R
BiFunction<Integer,Integer,Integer> add = (a,b) -> a+b;
๐Ÿ“ File Handling (java.io)
๐Ÿ“„
File Class
Create, check, delete files & folders
The File class lets you work with files and directories โ€” create, delete, check existence, list contents. It does NOT read/write content.
import java.io.File;

File f = new File("notes.txt");

// Create new file
f.createNewFile();       // returns true if created

// Check info
f.exists();              // true / false
f.getName();             // "notes.txt"
f.getAbsolutePath();     // full path
f.length();              // size in bytes
f.isFile();              // true
f.isDirectory();         // false
f.canRead();             // true/false
f.canWrite();            // true/false

// Delete
f.delete();

// Create directory
File dir = new File("myFolder");
dir.mkdir();             // one level
dir.mkdirs();            // nested dirs

// List all files in folder
String[] files = dir.list();
File[]   fileObjs = dir.listFiles();
โœ๏ธ
Write to File
FileWriter, BufferedWriter, PrintWriter
Use FileWriter for basic writing. Wrap in BufferedWriter for performance. Use PrintWriter for println-style writing.
import java.io.*;

// FileWriter โ€” basic write (overwrites!)
FileWriter fw = new FileWriter("notes.txt");
fw.write("Hello World\n");
fw.close(); // ALWAYS close!

// Append mode (add without overwriting)
FileWriter fw2 = new FileWriter("notes.txt", true);
fw2.write("New line\n");
fw2.close();

// BufferedWriter โ€” faster for large writes
BufferedWriter bw = new BufferedWriter(
    new FileWriter("notes.txt"));
bw.write("Line 1");
bw.newLine(); // platform-safe newline
bw.write("Line 2");
bw.close();

// PrintWriter โ€” easiest println style
PrintWriter pw = new PrintWriter("notes.txt");
pw.println("Hello");
pw.printf("Name: %s, Age: %d\n", "Ravi", 25);
pw.close();
๐Ÿ“–
Read from File
Scanner, BufferedReader, FileReader
Use Scanner for easy line-by-line reading. Use BufferedReader for faster performance with large files.
import java.io.*;
import java.util.Scanner;

// Scanner โ€” easiest way to read
File f = new File("notes.txt");
Scanner sc = new Scanner(f);
while (sc.hasNextLine()) {
    String line = sc.nextLine();
    System.out.println(line);
}
sc.close();

// BufferedReader โ€” faster for big files
BufferedReader br = new BufferedReader(
    new FileReader("notes.txt"));
String line;
while ((line = br.readLine()) != null) {
    System.out.println(line);
}
br.close();

// try-with-resources (auto-closes!)
try (BufferedReader r = new BufferedReader(
        new FileReader("notes.txt"))) {
    r.lines().forEach(System.out::println);
} // auto-closed here!
๐Ÿ”€
NIO Files (Modern Way)
java.nio.file.Files โ€” Java 7+
java.nio.file.Files is the modern, cleaner API for file operations. Preferred over old java.io for most tasks.
import java.nio.file.*;
import java.util.List;

Path p = Paths.get("notes.txt");

// Write (creates or overwrites)
Files.write(p, "Hello".getBytes());

// Write lines
List<String> lines = List.of("Line 1","Line 2");
Files.write(p, lines);

// Read all content as String
String content = Files.readString(p);

// Read all lines into List
List<String> all = Files.readAllLines(p);

// Copy / Move / Delete
Files.copy(p, Paths.get("backup.txt"));
Files.move(p, Paths.get("renamed.txt"));
Files.delete(p);

// Check
Files.exists(p);
Files.size(p);          // bytes
Files.isDirectory(p);
๐Ÿ“ฆ
Byte Streams
FileInputStream / FileOutputStream
Use byte streams for binary files (images, PDFs, audio). Work with raw bytes (0โ€“255) instead of characters.
import java.io.*;

// Write bytes
FileOutputStream fos = new FileOutputStream("img.dat");
byte[] data = {65, 66, 67}; // A, B, C
fos.write(data);
fos.close();

// Read bytes
FileInputStream fis = new FileInputStream("img.dat");
int b;
while ((b = fis.read()) != -1) {
    System.out.print((char) b); // ABC
}
fis.close();

// Buffered byte streams (faster)
BufferedInputStream  bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
๐Ÿ’ก
File I/O โ€” Quick Cheat Sheet
Task Best Class Note
Write text (simple) PrintWriter println style
Write text (fast) BufferedWriter Wrap FileWriter
Read text (simple) Scanner(File) hasNextLine loop
Read text (fast) BufferedReader readLine loop
Write binary FileOutputStream byte array
Read binary FileInputStream read() returns -1 at end
Modern all-in-one Files (NIO) readString / write
File info / delete File exists, mkdir, list
๐Ÿ’ก Always use try-with-resources: try (FileWriter fw = new FileWriter("f.txt")) { ... } โ€” file closes automatically even if exception occurs!
โŒจ๏ธ User Input (Scanner)
๐Ÿ“ฅ
Scanner Basics
Read from keyboard (System.in)
Scanner reads user input from the console. Import java.util.Scanner and create it with System.in.
import java.util.Scanner;

Scanner sc = new Scanner(System.in);

// Read a String (one word)
System.out.print("Enter name: ");
String name = sc.next();

// Read full line (with spaces)
System.out.print("Enter sentence: ");
String line = sc.nextLine();

// Read integer
System.out.print("Enter age: ");
int age = sc.nextInt();

// Read double
double price = sc.nextDouble();

// Read boolean
boolean flag = sc.nextBoolean(); // "true"/"false"

sc.close(); // good practice
โš ๏ธ
Scanner Gotchas & Patterns
Common bugs and fixes
// BUG: nextInt() leaves newline in buffer!
int age = sc.nextInt();
sc.nextLine(); // consume leftover newline
String name = sc.nextLine(); // now works!

// Multiple inputs on one line
// User types: "25 3.14 true"
int     a = sc.nextInt();
double  b = sc.nextDouble();
boolean c = sc.nextBoolean();

// Check before reading
if (sc.hasNextInt()) {
    int n = sc.nextInt();
}

// Loop until valid input
while (!sc.hasNextInt()) {
    System.out.println("Enter a number!");
    sc.next(); // discard bad input
}
int num = sc.nextInt();
๐Ÿ“Š
Scanner Method Reference
Method Reads Example Input
next() One word (String) "Hello"
nextLine() Full line "Hello World"
nextInt() Integer "42"
nextLong() Long "123456789"
nextDouble() Double "3.14"
nextFloat() Float "3.14"
nextBoolean() Boolean "true"
hasNext() Check word returns boolean
hasNextLine() Check line returns boolean
hasNextInt() Check int returns boolean
๐Ÿ“… Date & Time (java.time โ€” Java 8+)
๐Ÿ“…
LocalDate, LocalTime, LocalDateTime
Java 8 introduced java.time โ€” immutable, thread-safe date/time classes. Always prefer these over old Date/Calendar.
import java.time.*;

// Current date / time
LocalDate     date  = LocalDate.now();      // 2026-03-25
LocalTime     time  = LocalTime.now();      // 14:30:05
LocalDateTime both  = LocalDateTime.now(); // 2026-03-25T14:30

// Specific date/time
LocalDate d = LocalDate.of(2000, 12, 25);
LocalTime t = LocalTime.of(9, 30, 0);

// Get parts
date.getYear();        // 2026
date.getMonth();       // MARCH
date.getMonthValue(); // 3
date.getDayOfMonth(); // 25
date.getDayOfWeek();  // WEDNESDAY

// Add / subtract
date.plusDays(7);
date.minusMonths(2);
date.plusYears(1);
๐ŸŽจ
Format & Parse Dates
DateTimeFormatter
import java.time.*;
import java.time.format.DateTimeFormatter;

LocalDateTime now = LocalDateTime.now();

// Predefined formats
now.format(DateTimeFormatter.ISO_LOCAL_DATE);
// "2026-03-25"

// Custom format
DateTimeFormatter fmt =
    DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
String formatted = now.format(fmt);
// "25/03/2026 14:30"

// Parse string โ†’ LocalDate
LocalDate parsed = LocalDate.parse(
    "25/03/2026",
    DateTimeFormatter.ofPattern("dd/MM/yyyy")
);

// Format patterns:
// yyyy=year  MM=month  dd=day
// HH=hour(24) hh=hour(12) mm=min ss=sec
// E=day name  MMMM=full month name
โฑ๏ธ
Duration, Period & Comparisons
LocalDate d1 = LocalDate.of(2000, 1, 1);
LocalDate d2 = LocalDate.now();

// Period = date difference (years/months/days)
Period p = Period.between(d1, d2);
p.getYears();   // 26
p.getMonths();  // 2
p.getDays();    // 24

// Duration = time difference (hours/mins/secs)
LocalTime t1 = LocalTime.of(9,0);
LocalTime t2 = LocalTime.of(17,30);
Duration dur = Duration.between(t1, t2);
dur.toHours();   // 8
dur.toMinutes(); // 510

// Compare dates
d2.isAfter(d1);     // true
d2.isBefore(d1);    // false
d1.isEqual(d2);     // false
d2.compareTo(d1);   // positive
๐Ÿ“Š
Date/Time Quick Reference
Class Contains Example
LocalDate Date only 2026-03-25
LocalTime Time only 14:30:05
LocalDateTime Date + Time 2026-03-25T14:30
ZonedDateTime Date + Time + Zone ...+05:30[Asia/Kolkata]
Instant Timestamp (Unix) milliseconds since 1970
Period Date gap P26Y2M24D
Duration Time gap PT8H30M
DateTimeFormatter Format/Parse "dd/MM/yyyy"
๐Ÿ“ฆ Wrapper Classes
๐Ÿ”„
Wrapper Class Overview
Primitive โ†’ Object conversion
Wrapper classes convert primitive types into objects. Required for Collections (which can only hold objects, not primitives).
Primitive Wrapper Example
byte Byte Byte.valueOf((byte)5)
short Short Short.valueOf((short)10)
int Integer Integer.valueOf(42)
long Long Long.valueOf(100L)
float Float Float.valueOf(3.14f)
double Double Double.valueOf(3.14)
char Character Character.valueOf('A')
boolean Boolean Boolean.valueOf(true)
โšก
Autoboxing & Unboxing
Java auto-converts for you
// Autoboxing: primitive โ†’ Wrapper (auto)
Integer i = 42;       // int โ†’ Integer
Double  d = 3.14;    // double โ†’ Double
Boolean b = true;    // boolean โ†’ Boolean

// Unboxing: Wrapper โ†’ primitive (auto)
int    n = i;         // Integer โ†’ int
double x = d;        // Double โ†’ double

// Use in ArrayList (needs objects)
ArrayList<Integer> list = new ArrayList<>();
list.add(10);  // auto-boxed to Integer
int val = list.get(0); // auto-unboxed to int
๐Ÿ› ๏ธ
Wrapper Utility Methods
// Integer utilities
Integer.parseInt("42");       // String โ†’ int
Integer.toString(42);         // int โ†’ String
Integer.toBinaryString(10);   // "1010"
Integer.toHexString(255);     // "ff"
Integer.toOctalString(8);     // "10"
Integer.MAX_VALUE;               // 2147483647
Integer.MIN_VALUE;               // -2147483648
Integer.max(5, 10);            // 10
Integer.min(5, 10);            // 5
Integer.sum(5, 10);            // 15

// Double utilities
Double.parseDouble("3.14");
Double.isNaN(0.0/0.0);          // true
Double.isInfinite(1.0/0.0);    // true

// Character utilities
Character.isLetter('A');    // true
Character.isDigit('5');     // true
Character.toUpperCase('a');// 'A'
Character.isWhitespace(' ');
๐Ÿงฌ Generics
๐Ÿงฌ
Generic Class
Type-safe reusable classes
Generics allow you to write a class/method that works with any type while being type-safe. <T> is a type parameter (T = Type).
// Generic class: works with any type
class Box<T> {
    private T value;
    public Box(T val) { this.value = val; }
    public T get() { return value; }
}

// Use with Integer
Box<Integer> intBox = new Box<>(42);
intBox.get(); // 42 (int)

// Use with String
Box<String> strBox = new Box<>("Hello");
strBox.get(); // "Hello" (String)

// Multiple type params
class Pair<K, V> {
    K key; V value;
    public Pair(K k, V v) { key=k; value=v; }
}
โšก
Generic Methods & Wildcards
// Generic method
public static <T> void printArray(T[] arr) {
    for (T item : arr) System.out.println(item);
}

// Call with any type
printArray(new Integer[]{1,2,3});
printArray(new String[]{"a","b"});

// Bounded type: T must be Number or subclass
public static <T extends Number> double sum(T a, T b) {
    return a.doubleValue() + b.doubleValue();
}

// Wildcard ? = unknown type
public static void printList(List<?> list) {
    for (Object o : list) System.out.println(o);
}

// Upper bounded: List of Number or subclass
List<? extends Number> nums;
// Lower bounded: List of Number or superclass
List<? super Integer> ints;
๐Ÿ’ก Common type param names: T=Type, E=Element, K=Key, V=Value, N=Number, R=Return type
๐Ÿ”ข Enums (Enumerations)
๐Ÿ”ข
Enum Basics
Named constants group
An enum is a special class that represents a group of constants (unchangeable values). Use when a variable can only be one of a fixed set of values.
// Define enum
enum Day {
    MON, TUE, WED, THU, FRI, SAT, SUN
}

// Declare variable
Day today = Day.WED;

// Use in if
if (today == Day.WED) {
    System.out.println("Wednesday!");
}

// Use in switch
switch (today) {
    case SAT: case SUN:
        System.out.println("Weekend!"); break;
    default:
        System.out.println("Weekday");
}

// Loop all values
for (Day d : Day.values()) {
    System.out.println(d);
}
๐Ÿ› ๏ธ
Enum Methods & Fields
// Enum with fields and methods
enum Planet {
    MERCURY(3.303e+23, 2.4397e6),
    VENUS  (4.869e+24, 6.0518e6),
    EARTH  (5.976e+24, 6.37814e6);

    private final double mass;
    private final double radius;

    Planet(double mass, double radius) {
        this.mass = mass; this.radius = radius;
    }

    double surfaceGravity() {
        final double G = 6.67300E-11;
        return G * mass / (radius * radius);
    }
}

// Built-in enum methods
String name = Day.MON.name();    // "MON"
int    pos  = Day.MON.ordinal(); // 0 (index)
Day    d    = Day.valueOf("MON");// Day.MON
Day[]  all  = Day.values();       // all values
๐Ÿงต Threads & Concurrency
๐Ÿงต
Creating Threads
extend Thread or implement Runnable
A thread is a separate path of execution. Java can run multiple threads simultaneously. Two ways to create: extend Thread or implement Runnable.
// Way 1: extend Thread
class MyThread extends Thread {
    public void run() {
        System.out.println("Thread running!");
    }
}
MyThread t = new MyThread();
t.start(); // start() not run()!

// Way 2: implement Runnable (preferred)
class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Runnable!");
    }
}
Thread t2 = new Thread(new MyRunnable());
t2.start();

// Way 3: Lambda (simplest)
Thread t3 = new Thread(() -> {
    System.out.println("Lambda thread!");
});
t3.start();
โš™๏ธ
Thread Methods
Thread t = new Thread(() -> { /* ... */ });

t.start();             // begin execution
t.setName("Worker"); // give a name
t.getName();          // get name
t.setPriority(10);   // 1(low) to 10(high)
t.getPriority();      // default 5
t.isAlive();           // is still running?
t.join();              // wait for it to finish
t.interrupt();         // request stop

// Sleep (pause this thread)
try {
    Thread.sleep(1000); // sleep 1 second
} catch (InterruptedException e) { ... }

// Current thread info
Thread.currentThread().getName();
Thread.currentThread().getId();

// Thread states
// NEW โ†’ RUNNABLE โ†’ RUNNING โ†’ BLOCKED/WAITING โ†’ TERMINATED
๐Ÿ”’
Synchronization
Prevent race conditions
When multiple threads access shared data, use synchronized to allow only one thread at a time. Prevents race conditions.
class Counter {
    private int count = 0;

    // synchronized method
    public synchronized void increment() {
        count++;
    }

    // synchronized block (more fine-grained)
    public void add(int n) {
        synchronized(this) {
            count += n;
        }
    }
    public int getCount() { return count; }
}

// volatile: ensures visibility across threads
private volatile boolean running = true;
๐ŸŠ
ExecutorService (Thread Pool)
Instead of creating threads manually, use ExecutorService โ€” a managed thread pool that reuses threads for better performance.
import java.util.concurrent.*;

// Fixed thread pool (e.g. 3 threads)
ExecutorService exec =
    Executors.newFixedThreadPool(3);

// Submit tasks
exec.execute(() -> System.out.println("Task 1"));
exec.execute(() -> System.out.println("Task 2"));

// Submit with result (Future)
Future<Integer> future = exec.submit(() -> {
    Thread.sleep(100);
    return 42;
});
int result = future.get(); // blocks until done

// Shutdown (no new tasks)
exec.shutdown();
// Types: newCachedThreadPool(), newSingleThreadExecutor()
๐Ÿ” Regular Expressions (RegEx)
๐Ÿ”
Pattern & Matcher
java.util.regex
RegEx = patterns to search/match/replace text. Use Pattern to compile a regex and Matcher to apply it.
import java.util.regex.*;

// Simple: String.matches()
"Hello123".matches("[A-Za-z0-9]+"); // true

// Pattern + Matcher
Pattern p = Pattern.compile("\\d+"); // one+ digits
Matcher m = p.matcher("I have 3 cats and 12 dogs");

while (m.find()) {
    System.out.println(m.group()); // "3", "12"
}

// matches() โ€” whole string must match
m.reset();
boolean exact = m.matches();

// find() โ€” find anywhere in string
// group() โ€” get matched text
// start() โ€” match start index
// end()   โ€” match end index
๐Ÿ“š
RegEx Cheat Sheet
Pattern Meaning Example Match
. Any char except newline "a", "1", "@"
\d Digit [0-9] "5"
\D Non-digit "a", "@"
\w Word char [a-zA-Z0-9_] "hello"
\s Whitespace " ", "\t"
^ Start of string ^Hello
$ End of string World$
* 0 or more ab*c โ†’ ac, abc
+ 1 or more ab+c โ†’ abc, abbc
? 0 or 1 colou?r โ†’ color, colour
{n} Exactly n times \d{3} โ†’ "123"
[abc] One of a, b, c "a" or "b"
[^abc] Not a, b, or c "d", "1"
(a|b) a or b "cat" or "dog"
๐Ÿ”„
Replace & Split with RegEx
String s = "Hello   World  Java";

// replaceAll: replace pattern
s.replaceAll("\\s+", " ");   // "Hello World Java"
s.replaceFirst("\\d", "X"); // first digitโ†’X

// split: split by pattern
String[] words = s.split("\\s+"); // by spaces
// ["Hello", "World", "Java"]

// Common patterns for validation
String email = "user@example.com";
boolean validEmail = email.matches(
    "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}");

String phone = "9876543210";
boolean validPhone = phone.matches("[6-9]\\d{9}");

String zip = "440001";
boolean validZip = zip.matches("\\d{6}");
๐Ÿ” Iterator & List Sorting
๐Ÿ”
Iterator
Safe traversal with remove support
An Iterator lets you traverse any collection and safely remove elements while iterating (unlike for-each which throws ConcurrentModificationException).
import java.util.*;

ArrayList<String> list =
    new ArrayList<>(List.of("A","B","C","D"));

// Get iterator
Iterator<String> it = list.iterator();

// Loop: hasNext() โ†’ next()
while (it.hasNext()) {
    String s = it.next();
    if (s.equals("B")) {
        it.remove(); // SAFE remove during iteration!
    }
}
// list: ["A", "C", "D"]

// ListIterator โ€” can go backward too
ListIterator<String> li = list.listIterator();
while (li.hasNext())    { li.next(); }
while (li.hasPrevious()){ li.previous(); }

// Map iterator
Iterator<Map.Entry<String,Integer>> mi =
    map.entrySet().iterator();
๐Ÿ”ƒ
List Sorting
Comparable, Comparator, sort()
List<Integer> nums = new ArrayList<>(List.of(3,1,4,2));

// Natural sort (ascending)
Collections.sort(nums);          // [1,2,3,4]

// Reverse sort
Collections.sort(nums, Collections.reverseOrder());

// Lambda comparator
nums.sort((a, b) -> b - a);   // descending

// Sort strings by length
List<String> words = new ArrayList<>(List.of("banana","fig","apple"));
words.sort(Comparator.comparingInt(String::length));
// [fig, apple, banana]

// Custom object sort (Comparator)
List<Person> people = ...;
people.sort(Comparator.comparing(p -> p.name));
// or multi-level sort
people.sort(Comparator.comparing(Person::getName)
    .thenComparing(Person::getAge));
๐Ÿ†
Comparable Interface
Make your class sortable
// Implement Comparable to make class sortable
class Student implements Comparable<Student> {
    String name;
    int    grade;

    @Override
    public int compareTo(Student other) {
        return this.grade - other.grade; // asc grade
        // return other.grade - this.grade; // desc
        // return this.name.compareTo(other.name); // alpha
    }
}

// Now can use Collections.sort() directly
List<Student> students = ...;
Collections.sort(students); // uses compareTo
TreeSet<Student> ts = new TreeSet<>(students); // works!
๐Ÿš€ Advanced Topics
๐Ÿ“
Java Math Class
java.lang.Math โ€” no import needed
// Rounding
Math.round(3.7)      // 4
Math.floor(3.9)      // 3.0 (round down)
Math.ceil(3.1)       // 4.0 (round up)

// Power / root
Math.pow(2, 10)     // 1024.0
Math.sqrt(144)      // 12.0
Math.cbrt(27)       // 3.0 (cube root)

// Min / Max / Abs
Math.max(10, 20)    // 20
Math.min(10, 20)    // 10
Math.abs(-99)       // 99

// Logs
Math.log(10)        // natural log
Math.log10(1000)   // 3.0

// Trig (radians)
Math.sin(Math.PI/2)  // 1.0
Math.cos(0)           // 1.0
Math.PI                 // 3.14159...
Math.E                  // 2.71828...

// Random number [0.0, 1.0)
Math.random()         // 0.0 to 0.999
// Random int 0-99:
(int)(Math.random() * 100)
๐Ÿ“
StringBuilder & StringBuffer
StringBuilder is mutable โ€” modify without creating new objects. Much faster than + concatenation in loops. StringBuffer is thread-safe version.
StringBuilder sb = new StringBuilder();

sb.append("Hello");
sb.append(" ");
sb.append("World");

sb.insert(5, ",");       // insert at index
sb.delete(0, 5);        // delete range
sb.replace(0, 5, "Hi");// replace range
sb.reverse();           // reverse it
sb.length();            // length
sb.charAt(0);           // char at index
sb.indexOf("World");   // find substring
sb.toString();          // convert to String

// Good pattern for building strings in loops
StringBuilder result = new StringBuilder();
for (int i = 0; i < 100; i++) {
    result.append(i).append(",");
}
String s = result.toString();
๐Ÿ”ง
Collections Utility Methods
java.util.Collections
import java.util.Collections;

List<Integer> list = new ArrayList<>(List.of(3,1,4,1,5));

Collections.sort(list);          // [1,1,3,4,5]
Collections.reverse(list);       // [5,4,3,1,1]
Collections.shuffle(list);       // random order
Collections.min(list);           // 1
Collections.max(list);           // 5
Collections.frequency(list, 1); // 2 (count of 1s)
Collections.fill(list, 0);      // all zeros
Collections.nCopies(5, "x");   // [x,x,x,x,x]
Collections.swap(list, 0, 4);  // swap index 0โ†”4
Collections.disjoint(listA,listB); // no common?

// Unmodifiable wrappers
List<Integer> locked = Collections.unmodifiableList(list);
Map<String,Integer> lockedMap = Collections.unmodifiableMap(map);

// Synchronized wrappers (thread-safe)
List<Integer> synced = Collections.synchronizedList(list);
๐Ÿ’ก
Java Annotations
// Built-in annotations
@Override         // must match parent method
@Deprecated       // warns: don't use this
@SuppressWarnings("unchecked") // suppress warning
@FunctionalInterface // must have exactly one abstract method

// Example usage
class Animal {
    @Deprecated
    public void oldSound() { }

    public void sound() { }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Woof");
    }
}

// Custom annotation
public @interface MyAnnotation {
    String value() default "default";
}
๐Ÿ“ก
Java Algorithms (Collections)
// Binary search (list must be sorted first!)
List<Integer> sorted = List.of(1,3,5,7,9);
int idx = Collections.binarySearch(sorted, 5); // 2

// Arrays binary search
int[] arr = {1,3,5,7,9};
Arrays.binarySearch(arr, 7); // 3

// Streams sorting
List<Integer> asc = nums.stream()
    .sorted().collect(Collectors.toList());
List<Integer> desc = nums.stream()
    .sorted(Comparator.reverseOrder())
    .collect(Collectors.toList());

// Group by (very powerful!)
Map<Integer, List<String>> byLen = words.stream()
    .collect(Collectors.groupingBy(String::length));

// Count by condition
long count = nums.stream().filter(n -> n > 5).count();
๐Ÿท๏ธ
Records (Java 16+)
Compact data classes
Records are compact, immutable data classes. Java auto-generates: constructor, getters, equals(), hashCode(), toString().
// Old way: 20+ lines of boilerplate
// New way with record: 1 line!
record Point(int x, int y) {}

Point p = new Point(3, 4);
p.x();           // 3 (accessor method)
p.y();           // 4
p.toString();    // "Point[x=3, y=4]"

// With custom constructor
record Person(String name, int age) {
    // Compact constructor (validation)
    Person {
        if (age < 0) throw new IllegalArgumentException();
    }
    // Custom method
    boolean isAdult() { return age >= 18; }
}