Strongly-typed and object-oriented from the ground up โ the language behind AP Computer Science A, Android, and huge chunks of enterprise software. Copy-paste examples plus live Run/Submit exercises.
Every Java file's public class name must match the filename โ this one is Main.java.
public class Main {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
javac Main.java, then run with java Main โ Java compiles to bytecode, run by the Java Virtual Machine (JVM), not directly by your OS.main's String[] args parameter holds whatever gets typed after the program name when you launch it โ java Main hello world gives args = {"hello", "world"}.
public class Main {
public static void main(String[] args) {
System.out.println("Hello " + args[0]);
}
}
// running "java Main World" prints "Hello World"
args[0] when no argument was actually passed throws ArrayIndexOutOfBoundsException โ this is a runtime error, not something the compiler can catch for you.int age = 25;
double price = 9.99;
char grade = 'A';
boolean isValid = true;
String name = "Sam"; // capital S โ String is a class, not a primitive
int, double, char, boolean) hold their value directly โ think "cash in your pocket." Objects like String hold a reference to where the data lives โ think "an IOU pointing at the real thing."int x = 10, y = 3;
System.out.println(x / y); // 3 โ integer division truncates!
System.out.println(x / 2.0); // 5.0 โ use a double literal to keep the decimal
System.out.println(x % y); // 1 โ remainder
x += 5; // x = x + 5
x++; // increment
x--; // decrement
import java.util.Scanner;
Scanner sc = new Scanner(System.in);
System.out.print("Enter your age: ");
int age = sc.nextInt();
sc.nextLine(); // flush the leftover newline before the next nextLine() call
System.out.print("Enter your name: ");
String name = sc.nextLine();
System.out.println(name + " is " + age);
nextInt()/nextDouble() read the number but leave the trailing newline in the input buffer โ the very next nextLine() call then reads that leftover empty line instead of waiting for real input. Throw in an extra sc.nextLine(); right after any nextInt()/nextDouble() to clear it.System.out.printf("%s is %d\n", "Sam", 25); // %s string, %d int, %f float/double, %c char, %b boolean
System.out.printf("%.2f\n", 3.14159); // 3.14 โ precision
System.out.printf("%04d\n", 7); // 0007 โ zero-padded width
System.out.printf("%-6d|\n", 7); // "7 |" โ left-justify
// String.format uses the SAME %-codes, but RETURNS a string instead of printing it
String greeting = String.format("Hello, %s!", "Caleb");
System.out.println(greeting);
println, printf does not add a newline automatically โ include \n yourself. Reach for String.format when you need the formatted text as a value (to store, pass around, or concatenate) rather than print it immediately.System.out.println(Math.PI); // 3.141592653589793
System.out.println(Math.pow(2, 10)); // 1024.0
System.out.println(Math.sqrt(16)); // 4.0
System.out.println(Math.abs(-5)); // 5
System.out.println(Math.max(3, 9)); // 9
System.out.println(Math.round(4.6)); // 5
import java.util.Random;
Random random = new Random();
int roll = random.nextInt(6) + 1; // nextInt(6) gives 0-5, so +1 for a 1-6 die
double d = random.nextDouble();
boolean b = random.nextBoolean();
nextInt(bound)'s upper bound is exclusive โ nextInt(6) can never actually return 6.int age = 20;
if (age >= 18) {
System.out.println("Adult");
} else if (age >= 13) {
System.out.println("Teen");
} else {
System.out.println("Child");
}
Java 14+'s enhanced switch (arrow syntax) is the modern go-to over a long if/else-if chain โ no break needed, and it can return a value directly.
int day = 3;
String name = switch (day) {
case 1, 7 -> "Weekend"; // comma-separated multi-value case
case 2, 3, 4, 5, 6 -> "Weekday";
default -> "Invalid";
};
System.out.println(name);
int temp = 22;
if (temp > 0 && temp < 30) { // AND โ both must be true
System.out.println("Comfortable");
}
boolean isWeekend = false;
if (isWeekend || temp > 28) { // OR โ at least one true
System.out.println("Relax");
}
if (!isWeekend) { // NOT โ flips it
System.out.println("Back to work");
}
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
int n = 3;
while (n > 0) {
System.out.println(n);
n--;
}
int choice;
Scanner sc = new Scanner(System.in);
do { // runs the body at least ONCE, checks the condition after
System.out.print("Enter 1-3: ");
choice = sc.nextInt();
} while (choice < 1 || choice > 3);
for (int i = 0; i < 10; i++) {
if (i == 5) break; // stop button โ exits the loop entirely
if (i % 2 == 0) continue; // skip button โ skips just this iteration
System.out.println(i); // prints 1, 3
}
int[][] grid = {
{1, 2, 3},
{4, 5, 6}
};
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
System.out.print(grid[row][col] + " ");
}
System.out.println();
}
int[] nums = {10, 20, 30};
System.out.println(nums[0]); // 10
System.out.println(nums.length); // 3 โ length is a field, not a method
for (int n : nums) { // enhanced for loop
System.out.println(n);
}
import java.util.Arrays;
Arrays.sort(nums); // sorts in place (Arrays.parallelSort for very large arrays)
System.out.println(Arrays.toString(nums));
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a == b); // false โ different array objects
System.out.println(a.equals(b)); // false โ array .equals() is STILL identity-based!
System.out.println(Arrays.equals(a, b)); // true โ this is the one that compares CONTENTS
int[] filled = new int[5];
Arrays.fill(filled, 7); // {7, 7, 7, 7, 7}
0..length-1 throws ArrayIndexOutOfBoundsException โ unlike C, Java always checks bounds for you (at a small runtime cost). And arrays never override .equals(), so it silently falls back to identity comparison โ always use Arrays.equals() (or Arrays.deepEquals() for a 2D array) to compare contents.String[] names = {"Ada", "Linus", "Grace"};
String target = "Linus";
boolean found = false;
for (String n : names) {
if (n.equals(target)) { found = true; break; }
}
System.out.println(found);
String with == checks identity, not content โ always use .equals() when searching for a matching value.A resizable array โ the everyday alternative to fixed-size arrays. Elements must be objects (wrapper classes for primitives), hence the diamond <>.
import java.util.ArrayList;
import java.util.Collections;
ArrayList<String> names = new ArrayList<>();
names.add("Ada");
names.add("Linus");
names.set(0, "Grace"); // replace at index
System.out.println(names.get(0)); // Grace
System.out.println(names.size()); // 2
names.remove("Linus");
Collections.sort(names);
Collections.reverse(names); // flips the current order in place
import java.util.Arrays;
import java.util.List;
List<String> fixed = Arrays.asList("Ada", "Linus"); // quick array-to-List, one line
List is the interface โ the "steering wheel." ArrayList and LinkedList are two different "engines" underneath it, both usable through the exact same List methods.
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
List<Integer> grades = new ArrayList<>(); // fast random access by index
List<Integer> queue = new LinkedList<>(); // fast insert/remove at the ends
grades.add(90);
queue.add(1);
// both are used identically through the List interface โ .add/.get/.size all work the same
List interface (rather than declaring a variable as ArrayList directly) means you can swap the underlying implementation later without touching any of the code that uses it.String name = " Mo Salah ";
System.out.println(name.length()); // includes the spaces
System.out.println(name.trim()); // "Mo Salah" โ strips leading/trailing whitespace
System.out.println(name.toUpperCase()); // " MO SALAH "
System.out.println(name.trim().substring(0, 2)); // "Mo"
System.out.println(name.contains("Salah")); // true
System.out.println(name.indexOf("Salah")); // index where it starts
System.out.println(name.replace("Mo", "M."));
System.out.println(name.trim().equalsIgnoreCase("mo salah")); // true
String a = "hi", b = "hi";
System.out.println(a == b); // true โ identical literals share ONE cached object ("interning")
String c = new String("hi");
System.out.println(a == c); // false โ c was built fresh, a separate object in memory
== compares object identity in Java, not content. Always use .equals() (or .equalsIgnoreCase()) to compare String values โ == can *look* like it works for simple literals (Java caches/"interns" identical literals to the same object), but that's a coincidence of the cache, not a content comparison, and it breaks the moment a string is built with new String(...) or produced at runtime.public static int add(int a, int b) {
return a + b;
}
Java is always pass-by-value โ but for an object parameter, the "value" being copied is the reference itself, not the object. So the copy still points at the exact same object, and mutating its fields through that copy is visible to the caller.
static void changeInt(int x) {
x++; // only the LOCAL copy changes
}
static void changeName(StringBuilder name) {
name.append("!"); // mutates the SAME object the caller has
}
public static void main(String[] args) {
int n = 5;
changeInt(n);
System.out.println(n); // 5 โ untouched
StringBuilder sb = new StringBuilder("Hi");
changeName(sb);
System.out.println(sb); // "Hi!" โ the caller's object WAS changed
}
An ellipsis (...) lets a method accept any number of arguments, packed into an array automatically โ avoids writing separate overloads for 2, 3, 4โฆ arguments.
public static int sum(int... numbers) {
int total = 0;
for (int n : numbers) total += n;
return total;
}
// sum(1, 2), sum(1, 2, 3, 4) โ both work with the same method
Two methods can share a name as long as their parameter lists differ โ the combination of name + parameter types is called the method's signature, and signatures must be unique.
public static int add(int a, int b) { return a + b; }
public static double add(double a, double b) { return a + b; }
// Java picks the right one based on the argument types you pass
public class Example {
int value = 10; // class-level (instance) scope โ visible to every method in this class
public void show() {
int value = 99; // LOCAL โ shadows the class-level "value" inside this method only
System.out.println(value); // 99
}
}
static members belong to the class itself, shared by every instance, rather than to any one object.
public class Friend {
static int numOfFriends = 0; // ONE shared counter for every Friend object
String name;
Friend(String name) {
this.name = name;
numOfFriends++;
}
}
// new Friend("Ada"); new Friend("Linus");
// Friend.numOfFriends is now 2 โ access static members via the CLASS name
static and private methods are the exception: they belong to the class (or are invisible outside it), so they can't be overridden.final means "can't be changed again," applied to three different things.
final int Y = 5;
Y = 10; // compile error: Y cannot be assigned a new value
public class User {
public final void sayHello() { /* ... */ } // a subclass CANNOT override this method
}
public final class Teacher extends User { } // no class can extend Teacher at all
final variable is C's/most languages' idea of a constant โ convention names them in ALL_CAPS, often as public static final class-level fields (e.g. public static final double PI = 3.14159;).public class Dog {
String name;
int age;
Dog(String n, int a) { // constructor
name = n;
age = a;
}
public void bark() {
System.out.println(name + " says woof!");
}
}
// Dog d = new Dog("Rex", 3); d.bark();
this refers to "the object currently being built/used" โ needed when a parameter name shadows a field. A class can also have several constructors with different parameter lists.
public class Student {
String name;
int age;
Student(String name) { // only a name given โ default the age
this.name = name; // this.name = the FIELD, name = the PARAMETER
this.age = 18;
}
Student(String name, int age) { // overloaded constructor โ both given
this.name = name;
this.age = age;
}
}
public class Animal {
String name;
Animal(String name) { this.name = name; }
public void eat() { System.out.println(name + " is eating..."); }
}
public class Cat extends Animal { // Cat inherits everything from Animal
Cat(String name) {
super(name); // must call the parent's constructor first
}
public void meow() { System.out.println("Meow!"); }
}
// Cat c = new Cat("Whiskers"); c.eat(); c.meow(); -- both work
A subclass can replace ("override") an inherited method with its own version. @Override tells the compiler to double-check the signature actually matches โ it catches typos that would otherwise silently create a brand-new method instead of overriding.
public class Animal {
public void speak() { System.out.println("..."); }
}
public class Dog extends Animal {
@Override
public void speak() { System.out.println("Woof!"); } // overrides the parent version
@Override
public String toString() { // every object inherits a default (unhelpful) toString()
return "Dog object"; // print/println/printf all call this automatically
}
}
An abstract class can't be instantiated directly โ it exists to be extended. It can mix abstract methods (no body; subclasses must implement them) with regular, fully-implemented methods that subclasses just inherit.
public abstract class Shape {
public abstract double area(); // no body โ every subclass MUST implement this
public void describe() { // concrete โ inherited as-is
System.out.println("Area: " + area());
}
}
public class Circle extends Shape {
double radius;
Circle(double r) { radius = r; }
public double area() { return Math.PI * radius * radius; }
}
An object can be treated as its supertype, and Java decides at runtime which overridden method actually runs, based on the object's real type โ not the variable's declared type.
Shape[] shapes = { new Circle(2), new Circle(5) };
for (Shape s : shapes) {
s.describe(); // each call runs the correct subclass's area() automatically
}
An interface defines a contract โ any class that implements it must provide those methods. A class can implement multiple interfaces (unlike single-parent-only inheritance).
public interface Prey {
void flee();
}
public interface Predator {
void hunt();
}
public class Fox implements Prey, Predator { // implements BOTH
public void flee() { System.out.println("Fox runs away"); }
public void hunt() { System.out.println("Fox hunts a rabbit"); }
}
Keep fields private and expose controlled access through getters/setters โ this lets a setter validate input, and a missing setter makes a field effectively read-only from outside the class.
public class Product {
private double price;
public double getPrice() { return price; }
public void setPrice(double p) {
if (p >= 0) price = p; // validation lives right here, in one place
}
}
// a field with a getter but NO setter โ the only way to set it is through the constructor,
// so once the object exists, that value can never change again
public class Point {
private final int x;
Point(int x) { this.x = x; }
public int getX() { return x; }
}
Aggregation ("has-a"): a Library has Book objects, but those books can exist independently of the library. Composition ("part-of," tighter): a Car is composed of an Engine โ conceptually, the engine only makes sense as part of that specific car.
public class Engine { int horsepower; }
public class Car {
private final Engine engine = new Engine(); // composition: Car OWNS its Engine
}
public class Library {
ArrayList<Book> books; // aggregation: books can outlive the Library
}
Every primitive has an object "wrapper" (intโInteger, doubleโDouble, charโCharacter, booleanโBoolean) โ needed anywhere Java requires an object, like collections. Modern Java converts back and forth automatically ("autoboxing").
Integer a = 123; // autoboxed from int automatically
int b = a; // auto-unboxed back to a primitive
System.out.println(Integer.parseInt("42") + 8); // 50 โ parseInt returns a primitive int
Integer boxed = Integer.valueOf("42"); // valueOf returns an Integer OBJECT instead
System.out.println(Character.isLetter('A')); // true
System.out.println(Integer.MAX_VALUE); // 2147483647 โ largest int
System.out.println(Integer.MIN_VALUE); // -2147483648
System.out.println(Integer.compare(3, 9)); // negative โ first three-way compare
System.out.println(Double.isNaN(Math.sqrt(-1))); // true โ sqrt of a negative isn't a real number
System.out.println(Math.pow(99999, 99999)); // Infinity โ silently overflows, doesn't crash
Double.POSITIVE_INFINITY/NEGATIVE_INFINITY or NaN ("not a number"). Check for these explicitly with Double.isNaN()/isInfinite()/isFinite() rather than assuming a normal number came back.double/float are floating-point and lose tiny amounts of precision โ fine for most math, risky for money. BigDecimal is fixed-point and exact.
import java.math.BigDecimal;
BigDecimal price = new BigDecimal("19.99"); // build from a STRING, not a double literal
BigDecimal tax = new BigDecimal("1.72");
System.out.println(price.add(tax)); // exact: 21.71, no floating-point drift
try/catch/finally handles runtime errors instead of crashing. Catch the most specific exception types first, and a generic Exception last, as a safety net.
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Can't divide by zero");
} catch (Exception e) {
System.out.println("Something else went wrong");
} finally {
System.out.println("This always runs");
}
import java.io.FileWriter;
import java.io.IOException;
try (FileWriter writer = new FileWriter("notes.txt")) {
writer.write("Score: 95");
} catch (IOException e) {
System.out.println("Couldn't write the file");
}
import java.io.BufferedReader;
import java.io.FileReader;
try (BufferedReader reader = new BufferedReader(new FileReader("notes.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("Couldn't read the file");
}
try (...) "try-with-resources" form automatically closes the writer/reader for you, even if an exception is thrown.import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
LocalDate today = LocalDate.now();
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("MM/dd/yyyy");
System.out.println(today.format(fmt));
LocalDate birthday = LocalDate.of(2010, 6, 15);
System.out.println(birthday.isBefore(today));
A generic class works with a placeholder type (<T>) decided when it's actually used โ this is exactly how ArrayList<E> itself is built.
public class Box<T> {
private T content;
public void set(T content) { this.content = content; }
public T get() { return content; }
}
Box<String> box = new Box<>();
box.set("hello");
System.out.println(box.get());
Key-value pairs โ keys are unique (adding a duplicate key overwrites the old value), values can repeat.
import java.util.HashMap;
HashMap<String, Integer> ages = new HashMap<>();
ages.put("Ada", 28);
ages.put("Linus", 34);
System.out.println(ages.get("Ada")); // 28
System.out.println(ages.containsKey("Linus")); // true
for (String key : ages.keySet()) {
System.out.println(key + ": " + ages.get(key));
}
A fixed set of named constants โ clearer and safer than comparing raw strings/numbers. Enum constants can even carry their own fields and constructor.
public enum Day {
SUNDAY(1), MONDAY(2), TUESDAY(3); // each constant gets its own constructor call
private final int number;
Day(int number) { this.number = number; }
public int getNumber() { return number; }
}
Day today = Day.MONDAY;
System.out.println(today.getNumber()); // 2
A one-off, nameless class definition โ handy when you need a single custom object and don't want to declare a whole named subclass just for it.
abstract class Greeting {
abstract void say();
}
Greeting g = new Greeting() { // defines AND instantiates a one-time subclass, right here
void say() { System.out.println("Hi there!"); }
};
g.say();
import java.util.Timer;
import java.util.TimerTask;
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
System.out.println("Time's up!");
timer.cancel(); // stop future scheduling
}
}, 3000); // delay in milliseconds
Implementing Runnable (preferred over extending Thread, since Java only allows single inheritance) lets a task run concurrently. .join() makes the main thread wait for a worker thread to finish.
public class Countdown implements Runnable {
public void run() {
try {
for (int i = 3; i > 0; i--) {
System.out.println(i);
Thread.sleep(1000);
}
} catch (InterruptedException e) { }
}
}
Thread t = new Thread(new Countdown());
t.start();
t.join(); // main thread waits here until t finishes
Full runnable programs, compiled and run in a real Java sandbox โ same workspace as the other cheat sheets.
public class Main {
public static void main(String[] args) {
int[] nums = {4, 8, 15, 16, 23, 42};
int sum = 0;
for (int n : nums) sum += n;
System.out.println(sum);
}
}
public class Main {
public static void main(String[] args) {
String s = "pointers";
String reversed = new StringBuilder(s).reverse().toString();
System.out.println(reversed);
}
}
public class Main {
public static void main(String[] args) {
double kg = 10;
System.out.printf("%.2f kg = %.2f lb\n", kg, kg * 2.2046);
}
}
public class Main {
public static int fib(int n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
public static void main(String[] args) {
System.out.println(fib(10));
}
}
public class Main {
static class Rectangle {
double width, height;
Rectangle(double w, double h) { width = w; height = h; }
double area() { return width * height; }
}
public static void main(String[] args) {
Rectangle r = new Rectangle(4, 5);
System.out.println(r.area());
}
}
public class Main {
public static void main(String[] args) {
double principal = 1000, rate = 0.05, years = 10;
int n = 12;
double amount = principal * Math.pow(1 + rate / n, n * years);
System.out.printf("$%.2f\n", amount);
}
}
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
String text = "the cat sat on the mat the cat ran";
HashMap<String, Integer> counts = new HashMap<>();
for (String word : text.split(" ")) {
counts.put(word, counts.getOrDefault(word, 0) + 1);
}
for (String key : counts.keySet()) {
System.out.println(key + ": " + counts.get(key));
}
}
}
public class Main {
public static void main(String[] args) {
String[] questions = {
"What color is the sky?",
"How many days in a week?"
};
char[] answerKey = {'A', 'B'};
char[] guesses = {'a', 'b'}; // simulated, lowercase on purpose
int score = 0;
for (int i = 0; i < questions.length; i++) {
System.out.println(questions[i]);
char guess = Character.toUpperCase(guesses[i]);
if (guess == answerKey[i]) score++;
}
System.out.println("Score: " + score + "/" + questions.length);
}
}
public class Main {
static abstract class Shape {
abstract double area();
}
static class Circle extends Shape {
double r;
Circle(double r) { this.r = r; }
double area() { return Math.PI * r * r; }
}
static class Square extends Shape {
double side;
Square(double side) { this.side = side; }
double area() { return side * side; }
}
public static void main(String[] args) {
Shape[] shapes = { new Circle(3), new Square(4) };
for (Shape s : shapes) {
System.out.printf("%.2f\n", s.area()); // each call resolves to the right subclass at runtime
}
}
}
Prints six rows of Pascal's triangle by tracking each binomial coefficient incrementally instead of using factorials.
A perfect number equals the sum of its proper divisors (e.g. 6 = 1 + 2 + 3).
Validates the triangle inequality first, then classifies as equilateral, isosceles, or scalene.
A fixed-capacity stack built from a plain int[] and a top index โ no java.util.Stack involved.
An ArrayList<Student> gradebook where each Student computes its own average from an array of scores.
An abstract Employee base class with two subclasses that each override calculateSalary() differently โ resolved polymorphically at runtime.
An interface contract implemented by two unrelated classes, each satisfying it in its own way.
A hand-written Exception subclass, thrown with throws/throw and caught with a specific catch.
An enum whose own method computes the next state, driven by an enhanced switch on this.
A two-type-parameter generic class, used both with mixed types and matching types.
Uses put, get, and containsKey to track and adjust stock levels.
Computes a sum on a worker thread via an anonymous Runnable, then .join()s before reading the result on the main thread.