Java cheat sheets
Program basics
The shape of a program, printing, and the comments you can leave in it.
Explained in 1. Your first Java program and 2. Variables, types, and input/output
The smallest program (Java 25)
A compact source file: no class line needed. Run it with java Main.java.
void main() { IO.println("Hello");}The classic program
The file must be called Main.java, after the public class.
public class Main { public static void main(String[] args) { System.out.println("Hello"); }}Print with and without a new line
System.out.println("one line");System.out.print("no new line");System.out.printf("%d apples%n", 3);Comments
// to the end of the line/* across several lines */Variables and types
Every variable has a type that never changes. The common ones, and moving between them.
Explained in 2. Variables, types, and input/output, 3. Operators, expressions, and casting and 32. Wrapper classes and autoboxing
Declare and give a value
A char uses single quotes, a String double quotes.
int age = 30;double price = 9.99;boolean done = false;char grade = 'A';String name = "Ada";Let Java work out the type
var only works for local variables that get a value straight away. The type is still fixed.
var count = 10; // an intvar names = new ArrayList<String>();A value that never changes
final double TAX_RATE = 0.2;static final int MAX_USERS = 100; // inside a classWhole-number division and remainder
Dividing two ints drops the fraction. Make one side a double to keep it.
7 / 2 // 37 % 2 // 17 / 2.0 // 3.5-7 % 3 // -1Convert between number types
A cast to int cuts the fraction off. It does not round.
(int) 3.99 // 3(double) 7 / 2 // 3.5(char) ('a' + 1) // 'b'Math.round(2.5) // 3Limits and overflow
An int that goes past its limit wraps around without an error. Use long for big counts.
Integer.MAX_VALUE // 2147483647Integer.MAX_VALUE + 1 // -2147483648long big = 3_000_000_000L;Text to number and back
parseInt throws a NumberFormatException for text such as "4o".
Integer.parseInt("42") // 42Double.parseDouble("2.5") // 2.5String.valueOf(42) // "42""" + 3.0 // "3.0"Decisions and loops
Choosing what runs, and running it again.
Explained in 4. Making decisions: if, else and switch and 5. Loops: for, while, do-while
if, else if, else
if (score >= 90) { grade = 'A';} else if (score >= 80) { grade = 'B';} else { grade = 'C';}Pick a value with a condition
String label = age >= 18 ? "adult" : "child";switch with arrows
The arrow form never falls through to the next case, so it needs no break.
switch (day) { case "SAT", "SUN" -> System.out.println("weekend"); default -> System.out.println("weekday");}switch that produces a value
Inside a block, yield gives the switch its value.
int days = switch (month) { case 2 -> 28; case 4, 6, 9, 11 -> 30; default -> { System.out.println("long month"); yield 31; }};Count with a for loop
for (int i = 0; i < 5; i++) { System.out.println(i); // 0 to 4}Visit every element
The enhanced for loop works on arrays and on every collection.
for (String name : names) { System.out.println(name);}Repeat while a condition holds
A do loop always runs its body at least once.
while (balance < goal) { balance *= 1.05;}do { input = scanner.nextLine();} while (input.isBlank());Leave a loop early or skip a turn
outer:for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { if (grid[r][c] < 0) continue; // next c if (grid[r][c] == target) break outer; }}Arrays
A fixed number of values of one type, found by position.
Explained in 6. Arrays, one dimension and 8. Arrays, two dimensions, and practice
Make an array
int[] scores = new int[5]; // [0, 0, 0, 0, 0]int[] primes = {2, 3, 5, 7};String[] names = new String[3]; // [null, null, null]Length, first and last
primes[4] throws an ArrayIndexOutOfBoundsException: positions run from 0 to length minus 1.
primes.length // 4primes[0] // 2primes[primes.length - 1] // 7Print an array
Printing the array itself shows something like [I@1b6d3586.
Arrays.toString(primes) // "[2, 3, 5, 7]"Sort, fill and copy
Arrays.sort(scores);Arrays.fill(scores, -1);int[] longer = Arrays.copyOf(primes, 6); // [2, 3, 5, 7, 0, 0]Compare two arrays
a == b is only true when both names point at the same array.
Arrays.equals(a, b) // same length and same valuesA grid of rows and columns
int[][] grid = new int[3][4]; // 3 rows of 4grid[1][2] = 9; // row 1, column 2grid.length // 3grid[0].length // 4Arrays.deepToString(grid)Strings
Common String methods. A String never changes: each method returns a new one.
Explained in 20. Strings, StringBuilder, StringBuffer and 21. String practice problems
Length and one character
Positions start at 0, so the last one is length() - 1.
"hello".length() // 5"hello".charAt(1) // 'e'Compare the text
== asks whether two variables point at the same object, not whether the text matches.
a.equals(b)a.equalsIgnoreCase(b)a.compareTo(b) // negative, 0 or positiveCut and search
substring(1, 3) includes position 1 and stops before 3.
"hello".substring(1, 3) // "el""hello".indexOf('l') // 2"hello".contains("ell") // true"hello".startsWith("he") // trueChange case, trim and repeat
"Ada".toUpperCase() // "ADA"" hi ".strip() // "hi""ab".repeat(3) // "ababab""a-b".replace('-', '+') // "a+b"Empty and blank
"".isEmpty() // true" ".isEmpty() // false" ".isBlank() // trueSplit and join
split takes a regular expression: split on a dot with split("\\.").
String[] parts = "a,b,c".split(",");String joined = String.join("-", parts); // "a-b-c"Build a string with values in it
String.format("%s is %d", "Ada", 36) // "Ada is 36""%.2f".formatted(3.14159) // "3.14"Build a long string in a loop
Adding to a String in a loop makes a new string every time; a StringBuilder grows one buffer.
StringBuilder sb = new StringBuilder();for (int i = 0; i < 3; i++) { sb.append(i).append(' ');}String result = sb.toString(); // "0 1 2 "Text over several lines
A text block removes the indentation its lines and its closing quotes all share.
String poem = """ Roses are red, violets are blue. """;Methods and classes
Naming a piece of work, and designing your own types.
Explained in 12. Methods: parameters and return values, 11. Creating classes and objects, 13. Constructors, 14. Access modifiers and encapsulation and 26. The static and final keywords
A method that returns a value
static int square(int n) { return n * n;}square(4) // 16Any number of arguments
static int sum(int... nums) { int total = 0; for (int n : nums) total += n; return total;}sum(1, 2, 3) // 6A class with a constructor
this.name is the field; name alone is the parameter.
public class Dog { private final String name; private int age; public Dog(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } @Override public String toString() { return name + " (" + age + ")"; }}Make objects and use them
Dog rex = new Dog("Rex", 3);rex.getName() // "Rex"System.out.println(rex); // Rex (3)One value shared by the whole class
private static int created = 0; // one copy, not one per objectstatic int created() { return created; }Equal by content
Override both or neither: a HashSet uses hashCode first, then equals.
@Overridepublic boolean equals(Object o) { return o instanceof Dog d && d.name.equals(name) && d.age == age;} @Overridepublic int hashCode() { return Objects.hash(name, age); }Inheritance and interfaces
Sharing code between classes, and promising what a class can do.
Explained in 16. Inheritance, 17. Method overriding and super, 18. Polymorphism, 23. Abstract classes and 24. Interfaces
Extend a class
super(...) must be the first line of the constructor.
class Cat extends Animal { Cat(String name) { super(name); } @Override String sound() { return "Meow"; }}The object decides which method runs
Animal pet = new Cat("Tom");pet.sound() // "Meow", from CatA class that cannot be made, only extended
abstract class Shape { abstract double area(); String describe() { return "area " + area(); }}An interface with a default method
interface Greeter { String name(); default String greet() { return "Hello, " + name(); }} record Person(String name) implements Greeter {}Check the type and use it
The pattern names the cat c, so no separate cast is needed.
if (pet instanceof Cat c) { c.purr();}Records, enums and sealed types
Data classes in one line, fixed sets of values, and closed families of types.
Explained in 29. Records: data classes in one line, 28. Enums, lambdas, and functional interfaces and 30. Sealed types and pattern matching
A record
Records come with a constructor, accessors, equals, hashCode and toString.
record Point(int x, int y) {} Point p = new Point(1, 2);p.x() // 1p // Point[x=1, y=2]Check a record's values
record Range(int lo, int hi) { Range { if (lo > hi) throw new IllegalArgumentException("lo > hi"); }}An enum with a field
enum Size { SMALL(250), LARGE(500); final int millilitres; Size(int ml) { this.millilitres = ml; }} Size.LARGE.millilitres // 500Size.valueOf("SMALL") // SMALLA sealed family and a switch over it
No default needed: the compiler knows every kind of Shape.
sealed interface Shape permits Circle, Square {}record Circle(double r) implements Shape {}record Square(double side) implements Shape {} double area = switch (shape) { case Circle c -> Math.PI * c.r() * c.r(); case Square s -> s.side() * s.side();};Lists, maps and sets
Collections that grow, look things up by key, or keep one of each.
Explained in 7. ArrayList: a list that can grow, 34. The Collections Framework, 35. HashMap and HashSet: finding things fast, 37. Comparable, Comparator and sorting and 38. Stacks, queues and deques
A list that grows
List<String> names = new ArrayList<>();names.add("Ada");names.add(0, "Grace"); // insert at the frontnames.get(1) // "Ada"names.set(1, "Alan");names.remove("Grace");names.size() // 1A fixed list
List.of cannot change: add throws an UnsupportedOperationException.
List<Integer> nums = List.of(3, 1, 2);Look things up by key
Map<String, Integer> stock = new HashMap<>();stock.put("kiwi", 3);stock.get("kiwi") // 3stock.get("fig") // nullstock.getOrDefault("fig", 0) // 0stock.merge("kiwi", 1, Integer::sum); // now 4Walk through a map
A HashMap keeps no order. Use a TreeMap for sorted keys or a LinkedHashMap for insertion order.
for (Map.Entry<String, Integer> e : stock.entrySet()) { System.out.println(e.getKey() + " = " + e.getValue());}One of each
Set<String> seen = new HashSet<>();seen.add("x") // trueseen.add("x") // false, already thereSort a list
Collections.sort(names);people.sort(Comparator.comparing(Person::age));people.sort(Comparator.comparing(Person::age).reversed() .thenComparing(Person::name));Remove while looping
Calling names.remove inside a for-each loop throws a ConcurrentModificationException.
names.removeIf(n -> n.isBlank());Stacks, queues and priority
Deque<Integer> stack = new ArrayDeque<>();stack.push(1); stack.pop();Queue<String> line = new ArrayDeque<>();line.offer("a"); line.poll();PriorityQueue<Integer> pq = new PriorityQueue<>();pq.add(5); pq.add(1); pq.poll(); // 1, the smallestLambdas and streams
Passing behaviour around, and describing what to do with a collection.
Explained in 28. Enums, lambdas, and functional interfaces, 53. Streams: processing collections step by step, 54. Collectors and stream recipes and 55. Optional: a value that might be missing
Lambda shapes
x -> x * 2(a, b) -> a + b() -> "hello"s -> { System.out.println(s); }Method references
String::length // s -> s.length()System.out::println // x -> System.out.println(x)Integer::compare // (a, b) -> Integer.compare(a, b)Filter, change and collect
Nothing runs until the last call: streams are lazy.
List<String> loud = names.stream() .filter(n -> n.length() > 3) .map(String::toUpperCase) .toList();Add up and count
int total = nums.stream().mapToInt(Integer::intValue).sum();long big = nums.stream().filter(n -> n > 10).count();IntStream.rangeClosed(1, 5).sum() // 15Group and count
Map<Integer, Long> byLength = words.stream() .collect(Collectors.groupingBy(String::length, Collectors.counting()));A value that may be missing
Optional<String> first = names.stream().findFirst();first.orElse("nobody")first.map(String::length).orElse(0)Exceptions
Handling what goes wrong, and saying so yourself.
Explained in 48. Exception handling and 9. Reading errors and debugging
Catch an exception
try { int n = Integer.parseInt(text);} catch (NumberFormatException e) { System.out.println("Not a number: " + e.getMessage());} finally { System.out.println("always runs");}Several kinds in one catch
catch (IOException | IllegalStateException e) { ... }Close a resource for you
Anything opened in the parentheses is closed when the block ends, even after an exception.
try (BufferedReader in = Files.newBufferedReader(path)) { System.out.println(in.readLine());}Throw your own
if (amount <= 0) { throw new IllegalArgumentException("amount must be positive");}A custom exception
Extend Exception for a checked exception callers must handle, RuntimeException for one they need not.
class OutOfStockException extends Exception { OutOfStockException(String item) { super(item + " is out of stock"); }} void order(String item) throws OutOfStockException { ... }Keyboard and files
Reading what the user types, and reading and writing files.
Explained in 45. Scanner and console applications, 46. Reading files, 47. Writing files and 49. Path and Files: modern file handling
Read from the keyboard
nextInt leaves the Enter behind, so the next nextLine would read an empty line without the extra call.
Scanner in = new Scanner(System.in);int age = in.nextInt();in.nextLine(); // finish the lineString name = in.nextLine();Read a whole file
List<String> lines = Files.readAllLines(Path.of("notes.txt"));String text = Files.readString(Path.of("notes.txt"));Write a file
Without APPEND, writing replaces what the file held.
Files.writeString(Path.of("out.txt"), "Hello\n");Files.writeString(Path.of("log.txt"), "more\n", StandardOpenOption.APPEND);Read line by line
try (BufferedReader in = Files.newBufferedReader(Path.of("data.csv"))) { String line; while ((line = in.readLine()) != null) { String[] fields = line.split(","); }}Check before reading
Reading a missing file throws a NoSuchFileException.
Files.exists(Path.of("notes.txt")) // true or falseDates, money and text patterns
java.time for dates, BigDecimal for exact amounts, regular expressions for text.
Explained in 50. Dates and times with java.time, 51. Money and exact numbers: BigDecimal and BigInteger and 52. Regular expressions: patterns in text
Dates
Dates never change: plusDays returns a new date, so keep the result.
LocalDate d = LocalDate.of(2025, 3, 14);d.plusDays(30) // 2025-04-13d.getDayOfWeek() // FRIDAYLocalDate.parse("2025-12-25")Time between two dates
ChronoUnit.DAYS.between(start, end) // total daysPeriod.between(start, end) // like P2M14D: 2 months, 14 daysFormat a date for people
d.format(DateTimeFormatter.ofPattern("d MMM yyyy")) // "14 Mar 2025"Exact money
Make a BigDecimal from a string: new BigDecimal(0.1) keeps the double's tiny error.
BigDecimal price = new BigDecimal("19.99");BigDecimal total = price.multiply(new BigDecimal("3")); // 59.97total.setScale(1, RoundingMode.HALF_EVEN) // 60.0total.compareTo(new BigDecimal("59.970")) == 0 // trueCheck and change text with a pattern
In a Java string every backslash of the pattern is written twice.
"2025-03-14".matches("\\d{4}-\\d{2}-\\d{2}") // true"a1b22c333".replaceAll("\\d+", "#") // "a#b#c#"Find every match
Matcher m = Pattern.compile("\\d+").matcher("7 cats, 12 dogs");while (m.find()) { System.out.println(m.group()); // 7, then 12}Testing with JUnit
Small programs that check your code gives the right answers.
Explained in 22. Testing your code with JUnit
A test
Expected value first, then the actual one: the failure message reads them that way round.
class CalculatorTest { @Test void addsTwoNumbers() { assertEquals(5, Calculator.add(2, 3)); }}Compare doubles
assertEquals(0.3, 0.1 + 0.2, 1e-9); // within 0.000000001Expect an exception
assertThrows(IllegalArgumentException.class, () -> account.deposit(-5));A fresh object for every test
private Account account; @BeforeEachvoid setUp() { account = new Account(100); }One test, many inputs
@ParameterizedTest@ValueSource(ints = {0, -5, 1_000})void neverNegative(int n) { assertTrue(Math.abs(n) >= 0);}