Java Tutorial

Java is a class-based, object-oriented programming language designed to be platform-independent ("Write Once, Run Anywhere"). It runs on the JVM and is widely used for enterprise backends, Android development, and large-scale systems.

Syntax & Structure

Java
// HelloWorld.java - filename must match class name
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
        System.out.print("No newline");
        System.out.printf("Name: %s, Age: %d%n", "Alice", 25);
    }
}

// Compile and run
// javac HelloWorld.java
// java HelloWorld
► Try It Yourself

Data Types

TypeSizeRange / DescriptionExample
byte1 byte-128 to 127byte b = 127;
short2 bytes-32,768 to 32,767short s = 1000;
int4 bytes-2B to 2Bint n = 42;
long8 bytes-9.2-10-8 to 9.2-10-8long l = 99L;
float4 bytes6-7 decimal digitsfloat f = 3.14f;
double8 bytes15 decimal digitsdouble d = 3.14;
char2 bytesSingle Unicode characterchar c = 'A';
boolean1 bittrue / falseboolean ok = true;
StringvariableSequence of chars (reference type)String s = "Hi";
Java
// Type casting
int x = (int) 9.9;         // explicit cast (narrowing): 9
double d = 5;              // implicit cast (widening): 5.0
String s = String.valueOf(42);  // int ? String
int n = Integer.parseInt("42"); // String ? int

// var (type inference, Java 10+)
var list = new ArrayList<String>();
var message = "Hello";
► Try It Yourself

Strings

Java
String s = "Hello, World!";

s.length()                // 13
s.charAt(0)               // 'H'
s.indexOf("World")        // 7
s.substring(7)            // "World!"
s.substring(7, 12)        // "World"
s.toUpperCase()           // "HELLO, WORLD!"
s.toLowerCase()           // "hello, world!"
s.trim()                  // remove whitespace
s.strip()                 // modern trim (Java 11+)
s.replace("World", "Java")// "Hello, Java!"
s.contains("World")       // true
s.startsWith("Hello")     // true
s.endsWith("!")           // true
s.isEmpty()               // false
s.isBlank()               // false (Java 11+)
s.split(", ")             // ["Hello", "World!"]
String.join(", ", "a","b","c"); // "a, b, c"
s.equals("Hello, World!") // true  (use equals, not ==)
s.equalsIgnoreCase("hello, world!")  // true
s.compareTo("abc")        // lexicographic comparison

// StringBuilder (mutable - efficient for many appends)
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(", ").append("World").append("!");
sb.insert(5, " there");
sb.delete(0, 5);
sb.reverse();
String result = sb.toString();

// String.format (printf style)
String msg = String.format("Name: %s, Score: %d", "Alice", 95);

// Text blocks (Java 13+)
String json = """
    {
        "name": "Alice",
        "age": 25
    }
    """;
► Try It Yourself

Classes & Objects

Java
public class Person {
    // Instance variables (fields)
    private String name;
    private int age;

    // Constructor
    public Person(String name, int age) {
        this.name = name;
        this.age  = age;
    }

    // Getters & Setters
    public String getName() { return name; }
    public void   setName(String name) { this.name = name; }
    public int    getAge()  { return age;  }
    public void   setAge(int age) {
        if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
        this.age = age;
    }

    // Instance method
    public String greet() {
        return "Hello, I'm " + name + ", " + age + " years old.";
    }

    // Override toString
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

// Usage
Person p = new Person("Alice", 25);
System.out.println(p.greet());     // "Hello, I'm Alice, 25 years old."
p.setAge(26);
System.out.println(p);             // Person{name='Alice', age=26}
► Try It Yourself

Inheritance & Polymorphism

Java
// Superclass
public class Shape {
    protected String color;

    public Shape(String color) { this.color = color; }

    public double area() { return 0; }

    @Override
    public String toString() { return color + " shape, area=" + area(); }
}

// Subclass
public class Circle extends Shape {
    private double radius;

    public Circle(String color, double radius) {
        super(color);              // call parent constructor
        this.radius = radius;
    }

    @Override
    public double area() {         // method overriding
        return Math.PI * radius * radius;
    }
}

public class Rectangle extends Shape {
    private double w, h;
    public Rectangle(String color, double w, double h) {
        super(color); this.w = w; this.h = h;
    }
    @Override public double area() { return w * h; }
}

// Polymorphism
Shape[] shapes = { new Circle("red", 5), new Rectangle("blue", 4, 6) };
for (Shape s : shapes) {
    System.out.printf("Area: %.2f%n", s.area()); // calls overridden method
}

// instanceof
if (shapes[0] instanceof Circle c) {   // pattern matching (Java 16+)
    System.out.println("Radius: " + c.radius);
}
► Try It Yourself

Collections Framework

Java
import java.util.*;

// ArrayList
List<String> list = new ArrayList<>();
list.add("apple"); list.add("banana");
list.get(0);         // "apple"
list.size();         // 2
list.remove("apple");
list.contains("banana"); // true
Collections.sort(list);

// LinkedList
List<String> linked = new LinkedList<>(list);

// HashMap
Map<String, Integer> map = new HashMap<>();
map.put("a", 1); map.put("b", 2);
map.get("a");    // 1
map.getOrDefault("z", 0); // 0
map.containsKey("a");     // true
map.entrySet();   // set of key-value entries
for (Map.Entry<String, Integer> e : map.entrySet()) {
    System.out.println(e.getKey() + "=" + e.getValue());
}

// HashSet (no duplicates)
Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 2, 3));
// {1, 2, 3}

// ArrayDeque (stack & queue)
Deque<Integer> queue = new ArrayDeque<>();
queue.offer(1); queue.offer(2);  // enqueue
queue.poll();                     // dequeue (1)
queue.peek();                     // peek (2, no removal)
► Try It Yourself

Lambdas & Streams (Java 8+)

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

List<Integer> nums = Arrays.asList(5, 3, 8, 1, 9, 2, 7);

// Lambda - no-name method
Runnable r = () -> System.out.println("Hello");
Comparator<Integer> comp = (a, b) -> a - b;

// Streams pipeline
int sumOfEvenSquares = nums.stream()
    .filter(n -> n % 2 == 0)         // keep even numbers
    .map(n -> n * n)                  // square them
    .reduce(0, Integer::sum);         // sum all

// Collectors
List<String> words = Arrays.asList("banana","apple","cherry","avocado");
Map<Character, List<String>> byLetter = words.stream()
    .collect(Collectors.groupingBy(w -> w.charAt(0)));

// Common stream operations
words.stream()
    .filter(w -> w.length() > 5)
    .sorted()
    .distinct()
    .map(String::toUpperCase)
    .limit(3)
    .forEach(System.out::println);

// Create list from stream
List<String> result = words.stream()
    .filter(w -> w.startsWith("a"))
    .collect(Collectors.toList());

// Optional (avoid null)
Optional<String> opt = words.stream().findFirst();
opt.ifPresent(System.out::println);
String val = opt.orElse("default");
► Try It Yourself

Packages & Access Modifiers

Packages help you organize code, and access modifiers control what other classes can see.

ModifierVisible from
publicEverywhere
protectedSame package and subclasses
defaultSame package only
privateInside the same class only

File I/O

Java can read and write files using the modern NIO API, which is cleaner than older stream-only approaches for common tasks.

Java
import java.nio.file.Files;
import java.nio.file.Path;

String text = Files.readString(Path.of("notes.txt"));
Files.writeString(Path.of("output.txt"), text.toUpperCase());

Concurrency

Java supports threads, executors, and concurrent collections. Beginners do not need to master all of them immediately, but they should know that long-running work should not block the main application flow.