Skip to content · ⁨Saltar al contenido⁩
Subjects · ⁨Temas⁩
  • 1 Java basics · ⁨Conceptos básicos de Java⁩
    1.1

    Clases, método principal y salida

    English

    Every Java program lives inside a class 类. It starts at a method 方法 named main. System.out.println(...) prints a line; System.out.print(...) prints with no new line.

    • Java is compiled 编译: the compiler 编译器 checks the whole program, then it runs.
    • Every statement 语句 ends with a semicolon ;.
    Español

    Todo programa Java vive dentro de una clase 类. Comienza en un método 方法 llamado main. System.out.println(...) imprime una línea; System.out.print(...) imprime sin salto de línea.

    public class Main {
        public static void main(String[] args) {
            System.out.println("Hello, world!");
            System.out.println("I am learning Java.");
        }
    }
    
    • Java se compila 编译: el compilador 编译器 revisa todo el programa y luego lo ejecuta.
    • Cada sentencia 语句 termina con punto y coma ;.
    Los programas de Java viven en una clase y comienzan en main
    Los programas de Java viven en una clase y comienzan en main
    1.2

    Variables y tipos primitivos

    English

    A variable 变量 must declare 声明 its type. Common primitive types 基本类型: int (whole number), double (decimal), boolean (true/false), char (one letter).

    Español

    Una variable variable debe declarar su tipo. Tipos primitivos comunes 基本类型: int (número entero), double (decimal), boolean (true/false), char (una letra).

    public class Main {
        public static void main(String[] args) {
            int age = 17;
            double price = 9.99;
            boolean passed = true;
            System.out.println(age + " " + price + " " + passed);
        }
    }
    
    1.3

    Comentarios y estilo

    English

    A comment 注释 is // (one line) or /* ... */ (a block). Indent the code inside braces { }. Class names start Capitalised; variables and methods use camelCase 驼峰命名 (lowercase first).

    Common mistakes

    • Every statement ends with a semicolon ;.
    • main must be exactly public static void main(String[] args).
    • println adds a new line; print does not.
    Español

    Un comentario 注释 es // (una línea) o /* ... */ (un bloque). Indenta el código dentro de las llaves { }. Los nombres de clases empiezan con mayúscula; las variables y métodos usan camelCase 驼峰命名 (minúscula inicial).

    public class Main {
        public static void main(String[] args) {
            // greet the user
            String firstName = "Mei";
            System.out.println("Hi, " + firstName);
        }
    }
    

    Errores comunes

    • Toda sentencia termina con punto y coma ;.
    • main debe ser exactamente public static void main(String[] args).
    • println añade un salto de línea; print no lo hace.
  • 2 Operators & expressions · ⁨Operadores y expresiones⁩
    2.1

    Aritmética y asignación

    English

    Java arithmetic 算术 uses + - * / and % (remainder). With two ints, / is integer division 整数除法 — it drops the decimal. +=, -=, and ++ are shortcuts.

    Español

    La aritmética de Java 算术 usa + - * / y % (residuo). Con dos ints, / es división entera 整数除法 — elimina la parte decimal. +=, -= y ++ son atajos.

    public class Main {
        public static void main(String[] args) {
            int a = 7, b = 2;
            System.out.println(a / b);    // 3 (integer division)
            System.out.println(a % b);    // 1
            double x = 7.0 / 2;           // 3.5 (one side is double)
            System.out.println(x);
        }
    }
    
    int/int truncará; involucre un double para obtener un cociente real
    int/int truncará; involucre un double para obtener un cociente real
    2.2

    Usando objetos: String, Math, wrappers

    English

    Some values are objects 对象 with methods. String has .length(), .substring(), .toUpperCase(). Math has Math.max, Math.sqrt, Math.pow. Wrapper classes 包装类 (Integer, Double) wrap a primitive — e.g. Integer.parseInt("42").

    Math.random() returns a random 随机 double from 0.0 up to (but not including) 1.0. Scale it and cast to get whole numbers — this is the AP idiom:

    • Integer.MAX_VALUE (2147483647) and Integer.MIN_VALUE are the limits of int; going past them wraps around (an overflow).
    • An object variable that points at no object holds null; calling a method on it throws a NullPointerException.
    Español

    Algunos valores son objetos 对象 con métodos. String tiene .length(), .substring(), .toUpperCase(). Math tiene Math.max, Math.sqrt, Math.pow. Las clases wrapper 包装类 (Integer, Double) envuelven un primitivo — por ejemplo, Integer.parseInt("42").

    public class Main {
        public static void main(String[] args) {
            String s = "Hello";
            System.out.println(s.length());                  // 5
            System.out.println(s.toUpperCase());             // HELLO
            System.out.println(Math.max(3, 9));              // 9
            System.out.println(Integer.parseInt("42") + 1);  // 43
        }
    }
    

    Math.random() devuelve un aleatorio 随机 double desde 0.0 hasta (sin incluir) 1.0. Escálalo y conviértelo para obtener números enteros — esta es la idiomática AP:

    public class Main {
        public static void main(String[] args) {
            // a random whole number from 1 to 6 (a dice roll)
            int roll = (int) (Math.random() * 6) + 1;
            System.out.println(roll >= 1 && roll <= 6);   // true
        }
    }
    
    • Integer.MAX_VALUE (2147483647) y Integer.MIN_VALUE son los límites de int; pasarlo hace que se reenvuelva (un desbordamiento).
    • Una variable objeto que no apunta a ningún objeto contiene null; llamar un método sobre ella lanza un NullPointerException.
    2.3

    Conversión y cambio de tipo

    English

    A cast 强制转换 changes a value's type. (int) drops the decimal; (double) avoids integer division when you need an exact result.

    Common mistakes

    • Integer division: 5 / 2 is 2, not 2.5. Cast first: (double) 5 / 2.
    • Compare Strings (and other objects) with .equals(), not ==.
    • == on two objects tests whether they are the SAME object, not whether they look equal.
    Español

    Un cast 强制转换 cambia el tipo de un valor. (int) elimina la parte decimal; (double) evita la división entera cuando necesitas un resultado exacto.

    public class Main {
        public static void main(String[] args) {
            double pi = 3.99;
            System.out.println((int) pi);            // 3
            int total = 7, n = 2;
            System.out.println((double) total / n);  // 3.5
        }
    }
    

    Errores comunes

    • División entera: 5 / 2 es 2, no 2.5. Castea primero: (double) 5 / 2.
    • Compara Strings (y otros objetos) con .equals(), no con ==.
    • == en dos objetos prueba si son el MISMO objeto, no si se ven iguales.
  • 3 Booleans & selection · ⁨Booleanos y selección⁩
    3.1

    if / else

    English

    if runs a block when a condition 条件 is true; else if and else add more cases. The condition goes in ( ), the block in { }.

    Español

    if ejecuta un bloque cuando una condición es verdadera; else if y else añaden más casos. La condición va entre paréntesis ( ), y el bloque entre llaves { }.

    public class Main {
        public static void main(String[] args) {
            int score = 72;
            if (score >= 80) {
                System.out.println("A");
            } else if (score >= 60) {
                System.out.println("B");
            } else {
                System.out.println("fail");
            }
        }
    }
    
    if elige la rama verdadera; else la rama falsa
    if elige la rama verdadera; else la rama falsa
    3.2

    Operadores lógicos y comparaciones

    English

    Compare with ==, !=, <, >, <=, >= — a comparison 比较 gives a boolean. Combine with && (and), || (or), ! (not) — the logical operators 逻辑运算符. For Strings, use .equals(...), not ==.

    Español

    Compare con ==, !=, <, >, <=, >= — una comparación devuelve un valor de tipo boolean. Combine con && (y), || (o), ! (no) — los operadores lógicos. Para objetos String, utilice .equals(...), no ==.

    public class Main {
        public static void main(String[] args) {
            int age = 16;
            boolean member = true;
            System.out.println(age >= 18 && member);   // false
            String a = "hi";
            System.out.println(a.equals("hi"));        // true
        }
    }
    
    3.3

    switch

    English

    switch chooses among many fixed values. Each case ends with break; default is the fallback.

    Common mistakes

    • A condition must be a boolean; if (x = 5) does not compile (use ==).
    • Each switch case needs a break;, or control falls through to the next case.
    • && and || are the logical operators; & and | are bitwise.
    Español

    switch elige entre varios valores fijos. Cada case debe terminar con break; default sirve como opción por defecto.

    public class Main {
        public static void main(String[] args) {
            int day = 3;
            switch (day) {
                case 1: System.out.println("Mon"); break;
                case 3: System.out.println("Wed"); break;
                default: System.out.println("other");
            }
        }
    }
    

    Errores comunes

    • Una condición debe ser de tipo boolean; if (x = 5) no compila (utilice ==).
    • Cada caso en un switch necesita un break;, de lo contrario el control caerá al siguiente caso.
    • && y || son los operadores lógicos; & y | son operadores bit a bit.
  • 4 Loops · ⁨Bucles⁩
    4.1

    bucles while

    English

    A while loop repeats while a condition is true. Change something inside, or it loops forever.

    Español

    Un bucle while se repite mientras una condición sea verdadera. Si no se modifica algo en su interior, el bucle se ejecutará indefinidamente.

    public class Main {
        public static void main(String[] args) {
            int n = 1;
            while (n <= 3) {
                System.out.println(n);
                n++;
            }
        }
    }
    
    el bucle while verifica la condición antes de cada paso del cuerpo
    El bucle while verifica la condición antes de cada paso del cuerpo
    4.2

    bucles for

    English

    A for loop packs the start, the condition, and the step into one line. Best when you know the count.

    Español

    Un bucle for agrupa el inicio, la condición y el paso en una sola línea. Es ideal cuando se conoce la cantidad de iteraciones.

    public class Main {
        public static void main(String[] args) {
            for (int i = 0; i < 5; i++) {
                System.out.print(i + " ");
            }
            System.out.println();   // 0 1 2 3 4
        }
    }
    
    4.3

    Acumulación

    English

    The accumulator 累加器 pattern: start a variable before the loop, then update it each turn.

    Español

    El patrón del acumulador: iniciar una variable antes del bucle y luego actualizarla en cada vuelta.

    public class Main {
        public static void main(String[] args) {
            int total = 0;
            for (int i = 1; i <= 5; i++) {
                total += i;
            }
            System.out.println(total);   // 15
        }
    }
    
    4.4

    Bucle anidados

    English

    A loop inside a loop is a nested loop 嵌套循环. The inner loop runs fully on each turn of the outer one.

    Common mistakes

    • for (int i = 0; i < n; i++) runs n times (0 to n - 1); using <= runs one extra.
    • Do not put a semicolon right after for (...) or while (...) — it makes an empty loop.
    • Declare the counter in the for header so its scope ends with the loop.
    Español

    Un bucle dentro de otro es un bucle anidado. El bucle interno se ejecuta completamente en cada vuelta del bucle externo.

    public class Main {
        public static void main(String[] args) {
            for (int r = 0; r < 3; r++) {
                for (int c = 0; c < 3; c++) {
                    System.out.print("*");
                }
                System.out.println();
            }
        }
    }
    

    Errores comunes

    • for (int i = 0; i < n; i++) se ejecuta n veces (0 a n - 1); usar <= ejecuta una vez más.
    • No coloque un punto y coma inmediatamente después de for (...) o while (...), ya que esto crea un bucle vacío.
    • Declare el contador en el encabezado del for para que su alcance termine junto con el bucle.
  • 5 Strings · ⁨Cadenas (Strings)⁩
    5.1

    Métodos de cadenas

    English

    A String 字符串 is text. Useful methods: .length(), .charAt(i), .substring(a, b), .indexOf(x), .toUpperCase(), .equals(...). Strings are immutable 不可变 — each method returns a new String.

    The methods you will use every day:

    Method Meaning Example → result
    .length() how many characters "Hi".length() → 2
    .charAt(i) one character "Hi".charAt(0) → H
    .substring(a, b) part, stops before b "Python".substring(0, 3) → Pyt
    .substring(a) from a to the end "Python".substring(3) → hon
    .indexOf(x) first position, -1 if absent "banana".indexOf("na") → 2
    .equals(s) same text? "hi".equals("hi") → true
    .compareTo(s) order: negative / 0 / positive "apple".compareTo("banana") → negative

    compareTo puts Strings in dictionary order — the AP exam uses it for sorting questions:

    Español

    Una String cadena es texto. Métodos útiles: .length(), .charAt(i), .substring(a, b), .indexOf(x), .toUpperCase(), .equals(...). Las cadenas son inmutables — cada método devuelve una nueva String.

    public class Main {
        public static void main(String[] args) {
            String s = "Python";
            System.out.println(s.length());          // 6
            System.out.println(s.charAt(0));         // P
            System.out.println(s.substring(0, 3));   // Pyt
            System.out.println(s.toUpperCase());     // PYTHON
        }
    }
    

    Los métodos que usarás a diario:

    Método Significado Ejemplo → resultado
    .length() cuántos caracteres "Hi".length() → 2
    .charAt(i) un carácter "Hi".charAt(0) → H
    .substring(a, b) parte, se detiene antes de b "Python".substring(0, 3) → Pyt
    .substring(a) desde a hasta el final "Python".substring(3) → hon
    .indexOf(x) primera posición, -1 si está ausente "banana".indexOf("na") → 2
    .equals(s) ¿mismo texto? "hi".equals("hi") → true
    .compareTo(s) orden: negativo / 0 / positivo "apple".compareTo("banana") → negativo

    compareTo coloca las cadenas de texto en orden alfabético — el examen AP lo utiliza para preguntas de clasificación:

    public class Main {
        public static void main(String[] args) {
            String a = "apple", b = "banana";
            System.out.println(a.compareTo(b) < 0);    // true (apple comes first)
            System.out.println(a.compareTo("apple"));  // 0 (equal)
        }
    }
    
    Key String methods: length, charAt, substring, equals
    Métodos clave de Strings: length, charAt, substring, equals
    5.2

    Construcción y recorrido de cadenas

    English

    Join strings with + (concatenation 拼接). Visit each character with a loop and .charAt(i).

    When you build a long String in a loop, StringBuilder is much faster: append the pieces, then call .toString() once.

    Common mistakes

    • Strings are immutable: s.toUpperCase() returns a new String, so store the result.
    • Read a character with s.charAt(i); the length is s.length() (a method, with ()).
    • Building a String with += in a big loop is slow; use a StringBuilder.
    Español

    Une cadenas con + (concatenación). Visita cada carácter mediante un bucle y .charAt(i).

    public class Main {
        public static void main(String[] args) {
            String word = "banana";
            int count = 0;
            for (int i = 0; i < word.length(); i++) {
                if (word.charAt(i) == 'a') count++;
            }
            System.out.println(count);   // 3
        }
    }
    

    Al construir una cadena larga dentro de un bucle, StringBuilder es mucho más rápido: se concatenan las piezas y luego se llama a .toString() una sola vez.

    public class Main {
        public static void main(String[] args) {
            StringBuilder sb = new StringBuilder();
            for (int i = 1; i <= 5; i++) {
                sb.append(i).append(" ");
            }
            System.out.println(sb.toString().trim());   // 1 2 3 4 5
        }
    }
    

    Errores comunes

    • Las cadenas son inmutables: s.toUpperCase() devuelve una nueva cadena, por lo que debe almacenar el resultado.
    • Lea un carácter con s.charAt(i); la longitud es s.length() (un método, con ()).
    • Construir una cadena con += en un bucle grande es lento; utilice un StringBuilder.
  • 6 Arrays · ⁨Arreglos (Arrays)⁩
    6.1

    1-D arrays · ⁨Arreglos 1-D⁩

    English

    An array 数组 holds a fixed number of values of one type. Index from 0, and get the size with .length.

    Español

    Un array 数组 contiene un número fijo de valores de un mismo tipo. Los índices comienzan en 0, y se obtiene el tamaño con .length.

    public class Main {
        public static void main(String[] args) {
            int[] scores = {88, 71, 95};
            System.out.println(scores[0]);       // 88
            System.out.println(scores.length);   // 3
            scores[1] = 100;
            System.out.println(scores[1]);       // 100
        }
    }
    
    Un valor primitivo guarda su valor; una variable de array guarda una referencia al objeto array
    Un valor primitivo guarda su valor; una variable de array guarda una referencia al objeto array
    6.2

    Algoritmos de array

    English

    Walk the array with a loop to find a max, a total, a count, or to search 查找. A for-each loop (for (int x : a)) reads each value in turn.

    Español

    Recorra el array con un bucle para encontrar un máximo, un total, un conteo o para buscar 查找. Un bucle for-each (for (int x : a)) lee cada valor por turno.

    public class Main {
        public static void main(String[] args) {
            int[] a = {3, 9, 2, 7};
            int max = a[0], total = 0;
            for (int x : a) {
                if (x > max) max = x;
                total += x;
            }
            System.out.println(max + " " + total);   // 9 21
        }
    }
    
    6.3

    Arrays 2-D

    English

    A 2-D array 二维数组 is a grid 网格 of rows and columns: grid[row][col].

    Common mistakes

    • An array's size is a.length (no brackets, no ()), and it is fixed when created.
    • Valid indexes are 0 to a.length - 1; a[a.length] throws ArrayIndexOutOfBoundsException.
    • A new int[5] is filled with zeros, not left empty.
    Español

    Un array 2-D 二维数组 es una cuadrícula 网格 de filas y columnas: grid[row][col].

    public class Main {
        public static void main(String[] args) {
            int[][] grid = {{1, 2, 3}, {4, 5, 6}};
            System.out.println(grid[1][2]);   // 6
            for (int[] row : grid) {
                for (int v : row) System.out.print(v + " ");
            }
            System.out.println();             // 1 2 3 4 5 6
        }
    }
    

    Errores comunes

    • El tamaño de un array es a.length (sin corchetes, sin ()), y es fijo cuando se crea.
    • Los índices válidos van de 0 a a.length - 1; a[a.length] lanza ArrayIndexOutOfBoundsException.
    • Un nuevo int[5] se rellena con ceros, no queda vacío.
  • 7 ArrayList
    7.1

    Fundamentos de ArrayList

    English

    An ArrayList is a resizable 可变大小 list — it grows and shrinks as you add or remove items. It stores objects, so use a wrapper 包装类 type like Integer (not int). The <Integer> part is a generic 泛型 type. Key methods: .add(x), .get(i), .set(i, x), .size(), .remove(i).

    Español

    Un ArrayList es una lista de tamaño variable — crece y se encoge a medida que agregas o eliminas elementos. Almacena objetos, por lo que debes usar un tipo envoltorio (wrapper) como Integer (no int). La parte <Integer> es un tipo genérico (generic type). Métodos clave: .add(x), .get(i), .set(i, x), .size(), .remove(i).

    import java.util.ArrayList;
    
    public class Main {
        public static void main(String[] args) {
            ArrayList<Integer> nums = new ArrayList<Integer>();
            nums.add(10);
            nums.add(20);
            nums.add(30);
            System.out.println(nums.size());   // 3
            System.out.println(nums.get(1));   // 20
            nums.set(0, 99);
            System.out.println(nums);          // [99, 20, 30]
        }
    }
    
    ArrayList: add, get, size on a resizable list
    ArrayList: agregar, obtener, tamaño en una lista de tamaño variable
    7.2

    Algoritmos de ArrayList y el error de remove

    English

    .remove(i) shifts 移动 every later element one place left. If you remove while counting i up, you skip the next element. Fix: loop backwards, or don't increment i after a remove.

    Common mistakes

    • ArrayList uses .size(), .get(i) and .add(...) — not the [] you use on arrays.
    • Removing items while looping forward by index skips the next item (the remove bug). Loop backwards, or use an iterator.
    • Store objects, not primitives: use ArrayList<Integer>, and Java auto-boxes int values.
    Español

    .remove(i) desplaza cada elemento posterior un lugar hacia la izquierda. Si eliminas mientras cuentas i hacia arriba, omitirás el siguiente elemento. Solución: recorre el bucle hacia atrás, o no incrementes i después de una eliminación.

    import java.util.ArrayList;
    
    public class Main {
        public static void main(String[] args) {
            ArrayList<Integer> nums = new ArrayList<Integer>();
            for (int n : new int[]{4, 7, 4, 9, 4}) nums.add(n);
            // Remove every 4 — loop backwards so removals don't skip items.
            for (int i = nums.size() - 1; i >= 0; i--) {
                if (nums.get(i) == 4) nums.remove(i);
            }
            System.out.println(nums);   // [7, 9]
        }
    }
    

    Errores comunes

    • ArrayList utiliza .size(), .get(i) y .add(...) — no los corchetes [] que usas en los arrays.
    • Eliminar elementos mientras se itera hacia adelante por índice omite el siguiente elemento (el error de remove). Recorre hacia atrás, o usa un iterator.
    • Almacena objetos, no primitivas: usa ArrayList<Integer>, y Java hace el autoboxing automático de valores int.
  • 8 Writing classes · ⁨Escritura de clases⁩
    8.1

    Campos, constructor y métodos

    English

    A class 类 is a blueprint for objects. Its fields 字段 store data, its constructor 构造方法 sets up a new object, and its methods 方法 are the actions. this.name means "this object's name". Create an object with new.

    A static member belongs to the class itself, not to any one object. Call a static method on the class name — like Math.max — and a static field is shared by every object:

    Español

    Una clase (class) es un plano para objetos. Sus campos (fields) almacenan datos, su constructor (constructor) configura un nuevo objeto, y sus métodos (methods) son las acciones. this.name significa "el campo name de este objeto". Crea un objeto con new.

    public class Main {
        public static void main(String[] args) {
            Dog d = new Dog("Rex", 3);
            System.out.println(d.describe());   // Rex is 3 years old
            d.haveBirthday();
            System.out.println(d.describe());   // Rex is 4 years old
        }
    }
    
    class Dog {
        private String name;
        private int age;
    
        public Dog(String name, int age) {   // constructor
            this.name = name;
            this.age = age;
        }
    
        public String describe() {
            return name + " is " + age + " years old";
        }
    
        public void haveBirthday() {
            age++;
        }
    }
    

    Un miembro static pertenece a la propia clase, no a ningún objeto en particular. Llama a un método estático usando el nombre de la clase —como Math.max—, y un campo estático es compartido por todos los objetos:

    public class Main {
        public static void main(String[] args) {
            System.out.println(Counter.made());   // 0
            new Counter();
            new Counter();
            System.out.println(Counter.made());   // 2
        }
    }
    
    class Counter {
        private static int count = 0;      // shared by ALL Counter objects
    
        public Counter() { count++; }
    
        public static int made() {         // called on the class: Counter.made()
            return count;
        }
    }
    
    Los campos almacenan el estado; el constructor construye; los métodos actúan
    Los campos almacenan el estado; el constructor construye; los métodos actúan
    8.2

    Encapsulamiento

    English

    Encapsulation 封装 means hiding data behind methods. Mark fields private so outside code can't touch them directly; expose an accessor 访问方法 (getter) to read, and a method to change them safely. The method can guard the data — here a deposit must be positive.

    Common mistakes

    • A constructor has the class name and no return type (not even void).
    • Use this.field to tell a field apart from a parameter with the same name.
    • Make fields private and reach them through getter/setter methods (encapsulation).
    Español

    El encapsulamiento (encapsulation) significa ocultar los datos detrás de métodos. Marca los campos como private para que el código externo no pueda acceder a ellos directamente; expón un accesor (getter) para leerlos y un método para cambiarlos de forma segura. El método puede proteger los datos —aquí, un depósito debe ser positivo.

    public class Main {
        public static void main(String[] args) {
            Account a = new Account(100);
            a.deposit(50);
            a.deposit(-999);                       // rejected by the guard
            System.out.println(a.getBalance());    // 150
        }
    }
    
    class Account {
        private int balance;                       // hidden from outside
    
        public Account(int start) {
            balance = start;
        }
    
        public void deposit(int amount) {
            if (amount > 0) balance += amount;     // guard keeps balance valid
        }
    
        public int getBalance() {                  // accessor (getter)
            return balance;
        }
    }
    

    Errores comunes

    • Un constructor tiene el nombre de la clase y no tiene tipo de retorno (ni siquiera void).
    • Usa this.field para distinguir un campo de un parámetro con el mismo nombre.
    • Define los campos como private y accede a ellos mediante métodos getter/setter (encapsulamiento).
  • 9 Inheritance & polymorphism · ⁨Herencia y polimorfismo⁩
    9.1

    Herencia

    English

    Inheritance 继承 lets a subclass 子类 reuse a superclass 父类. Write class Cat extends Animal and Cat gets Animal's fields and methods for free. Call the parent constructor with super(...).

    Español

    La herencia (Inheritance) permite que una subclase reutilice un superclase. Escribe class Cat extends Animal y Cat obtendrá los campos y métodos de Animal gratuitamente. Llama al constructor del padre con super(...).

    public class Main {
        public static void main(String[] args) {
            Cat c = new Cat("Milo");
            c.eat();      // Milo is eating  (inherited from Animal)
            c.speak();    // Meow            (Cat's own method)
        }
    }
    
    class Animal {
        protected String name;
        public Animal(String name) { this.name = name; }
        public void eat() { System.out.println(name + " is eating"); }
    }
    
    class Cat extends Animal {
        public Cat(String name) { super(name); }     // call Animal's constructor
        public void speak() { System.out.println("Meow"); }
    }
    
    Cat y Dog extienden Animal: heredan sus miembros y añaden los suyos propios
    Gato y Perro extienden Animal: heredan sus miembros y añaden los suyos propios
    9.2

    Polimorfismo & toString

    English

    A subclass can override 重写 a method to replace the parent's version. Polymorphism 多态 means a Shape variable can hold any subtype, and Java picks the right toString at run time. System.out.println(obj) automatically calls obj.toString().

    Common mistakes

    • An overriding method must match the signature exactly; add @Override so the compiler catches slips.
    • super(...) must be the first line of a subclass constructor.
    • A subclass object IS-A superclass object, but not the other way round.
    Español

    Una subclase puede sobrescribir un método para reemplazar la versión del padre. El polimorfismo significa que una variable Shape puede contener cualquier subtipo, y Java elige el toString correcto en tiempo de ejecución. System.out.println(obj) llama automáticamente a obj.toString().

    public class Main {
        public static void main(String[] args) {
            Shape[] shapes = { new Circle(2), new Square(3) };
            for (Shape s : shapes) {
                System.out.println(s);          // each calls its own toString
            }
        }
    }
    
    class Shape {
        public String toString() { return "a shape"; }
    }
    
    class Circle extends Shape {
        private int r;
        public Circle(int r) { this.r = r; }
        public String toString() { return "Circle r=" + r; }     // override
    }
    
    class Square extends Shape {
        private int side;
        public Square(int side) { this.side = side; }
        public String toString() { return "Square side=" + side; }   // override
    }
    

    Errores comunes

    • Un método que sobrescribe debe coincidir exactamente con la firma; añade @Override para que el compilador detecte errores.
    • super(...) debe ser la primera línea de un constructor de subclase.
    • Un objeto de subclase ES UN objeto de superclase, pero no al revés.
  • 10 Recursion · ⁨Recursión⁩
    10.1

    Recursión

    English

    Recursion 递归 is a method that calls itself. Every recursion needs a base case 基准情形 (when to stop) and a recursive call 递归调用 that moves toward it. Without a base case it never stops and crashes with a stack overflow.

    Trace it: factorial(5) waits for factorial(4), which waits for factorial(3)… down to factorial(1) returning 1. Then the answers multiply back up: 1 → 2 → 6 → 24 → 120.

    Recursion also works on Strings — peel off one character each call:

    Merge sort 归并排序 is the recursive sort on the AP exam: split the array in half, sort each half recursively, then merge 合并 the two sorted halves. It runs in O(n log n) — far faster than the O(n²) sorts on big arrays.

    Common mistakes

    • Recursion needs a base case, or it throws StackOverflowError.
    • Each recursive call must move CLOSER to the base case.
    • Trace a small example by hand to check the recursion returns the right value.
    • In merge sort, the merge step does the real work; the recursion only splits the array.
    Español

    La recursión 递归 es un método que se llama a sí mismo. Toda recursión necesita un caso base 基准情形 (cuándo detenerse) y una llamada recursiva 递归调用 que la acerque a ese caso. Sin un caso base, nunca se detiene y falla con un desbordamiento de pila (stack overflow).

    La pila de llamadas para factorial(3): cada llamada espera, luego regresa en orden inverso
    La pila de llamadas para factorial(3): cada espera, luego retorna en orden inverso
    public class Main {
        public static void main(String[] args) {
            System.out.println(factorial(5));   // 120
        }
    
        public static int factorial(int n) {
            if (n <= 1) return 1;            // base case
            return n * factorial(n - 1);     // recursive call: n * (n-1)!
        }
    }
    

    Rastrea el proceso: factorial(5) espera a factorial(4), que espera a factorial(3)… hasta que factorial(1) retorna 1. Luego las respuestas se multiplican hacia arriba: 1 → 2 → 6 → 24 → 120.

    La recursión también funciona con Cadenas — separa un carácter por llamada:

    public class Main {
        public static void main(String[] args) {
            System.out.println(reverse("PYTHON"));   // NOHTYP
        }
    
        static String reverse(String s) {
            if (s.length() <= 1) return s;               // base case
            return reverse(s.substring(1)) + s.charAt(0);
        }
    }
    

    Merge sort 归并排序 es el ordenamiento recursivo en el examen AP: divide el array a la mitad, ordena cada mitad recursivamente, luego fusiona 合并 las dos mitades ordenadas. Ejecuta en O(n log n) — mucho más rápido que los ordenamientos O(n²) en arrays grandes.

    import java.util.Arrays;
    
    public class Main {
        public static void main(String[] args) {
            int[] a = {5, 2, 9, 1, 7, 3};
            mergeSort(a, 0, a.length - 1);
            System.out.println(Arrays.toString(a));   // [1, 2, 3, 5, 7, 9]
        }
    
        static void mergeSort(int[] a, int lo, int hi) {
            if (lo >= hi) return;                 // base case: one element
            int mid = (lo + hi) / 2;
            mergeSort(a, lo, mid);                // sort the left half
            mergeSort(a, mid + 1, hi);            // sort the right half
            merge(a, lo, mid, hi);                // merge the two halves
        }
    
        static void merge(int[] a, int lo, int mid, int hi) {
            int[] tmp = new int[hi - lo + 1];
            int i = lo, j = mid + 1, k = 0;
            while (i <= mid && j <= hi) {
                if (a[i] <= a[j]) tmp[k++] = a[i++];
                else              tmp[k++] = a[j++];
            }
            while (i <= mid) tmp[k++] = a[i++];
            while (j <= hi)  tmp[k++] = a[j++];
            for (k = 0; k < tmp.length; k++) a[lo + k] = tmp[k];
        }
    }
    

    Errores comunes

    • La recursión necesita un caso base, o lanzará StackOverflowError.
    • Cada llamada recursiva debe acercarse MÁS al caso base.
    • Rastrea un ejemplo pequeño a mano para verificar que la recursión retorna el valor correcto.
    • En merge sort, el paso de fusión hace el trabajo real; la recursión solo divide el array.
  • 11 Searching & sorting · ⁨Búsqueda y ordenamiento⁩
    11.1

    Búsqueda lineal y búsqueda binaria

    English

    Linear search 线性查找 checks every element — works on any array. Binary search 二分查找 is much faster but needs a sorted 已排序 array: it looks at the middle, then throws away half each step. Both return the index, or -1 if not found.

    Español

    La búsqueda lineal 线性查找 revisa cada elemento — funciona con cualquier arreglo. La búsqueda binaria 二分查找 es mucho más rápida, pero necesita un arreglo ordenado 已排序: examina el elemento central y descarta la mitad del rango en cada paso. Ambas devuelven el índice, o -1 si no se encuentra.

    public class Main {
        public static void main(String[] args) {
            int[] a = {2, 5, 8, 12, 16, 23};      // sorted, so binary search works
            System.out.println(linear(a, 12));    // 3
            System.out.println(binary(a, 12));    // 3
            System.out.println(binary(a, 9));     // -1 (not found)
        }
    
        static int linear(int[] a, int target) {
            for (int i = 0; i < a.length; i++)
                if (a[i] == target) return i;
            return -1;
        }
    
        static int binary(int[] a, int target) {
            int lo = 0, hi = a.length - 1;
            while (lo <= hi) {
                int mid = (lo + hi) / 2;
                if (a[mid] == target) return mid;
                else if (a[mid] < target) lo = mid + 1;
                else hi = mid - 1;
            }
            return -1;
        }
    }
    
    La búsqueda binaria reduce a la mitad el rango en cada paso, por lo que busca en un arreglo ordenado en O(log n)
    La búsqueda binaria reduce a la mitad el rango en cada paso, por lo que busca en un arreglo ordenado en O(log n)
    11.2

    Ordenamiento por selección e inserción

    English

    Selection sort 选择排序 repeatedly finds the smallest remaining value and swaps it to the front. Insertion sort 插入排序 takes each value and slides it back into its place among the already-sorted values.

    How the speeds compare:

    Algorithm Time
    linear search O(n)
    binary search O(log n), sorted arrays only
    selection / insertion sort O(n²)
    merge sort (topic 10) O(n log n)

    Common mistakes

    • Binary search only works on a sorted array.
    • Linear search is O(n); binary search is O(log n) but needs the sort first.
    • Selection and insertion sort are O(n²) — clear to learn, slow on big data.
    Español

    El ordenamiento por selección 选择排序 encuentra repetidamente el valor restante más pequeño y lo intercambia hacia el principio. El ordenamiento por inserción 插入排序 toma cada valor y lo desliza hacia atrás para colocarlo entre los valores ya ordenados.

    import java.util.Arrays;
    
    public class Main {
        public static void main(String[] args) {
            int[] a = {5, 2, 9, 1, 7};
            for (int i = 0; i < a.length - 1; i++) {
                int min = i;
                for (int j = i + 1; j < a.length; j++)
                    if (a[j] < a[min]) min = j;
                int t = a[min]; a[min] = a[i]; a[i] = t;   // swap into place
            }
            System.out.println(Arrays.toString(a));   // [1, 2, 5, 7, 9]
        }
    }
    
    import java.util.Arrays;
    
    public class Main {
        public static void main(String[] args) {
            int[] a = {5, 2, 9, 1, 7};
            for (int i = 1; i < a.length; i++) {
                int key = a[i], j = i - 1;
                while (j >= 0 && a[j] > key) {    // shift bigger values right
                    a[j + 1] = a[j];
                    j--;
                }
                a[j + 1] = key;                  // drop key into the gap
            }
            System.out.println(Arrays.toString(a));   // [1, 2, 5, 7, 9]
        }
    }
    

    Comparación de velocidades:

    Algoritmo Tiempo
    búsqueda lineal O(n)
    búsqueda binaria O(log n), solo arreglos ordenados
    ordenamiento por selección / inserción O(n²)
    ordenamiento por fusión (tema 10) O(n log n)

    Errores comunes

    • La búsqueda binaria solo funciona en un arreglo ordenado.
    • La búsqueda lineal es O(n); la búsqueda binaria es O(log n) pero requiere primero el ordenamiento.
    • El ordenamiento por selección y por inserción son O(n²) — fáciles de aprender, lentos con grandes volúmenes de datos.
  • 12 Files & the FRQ · ⁨Archivos y la AP FRQ⁩
    12.1

    Archivos de texto con Scanner

    English

    A Scanner reads text one line at a time. For a real file you write new Scanner(new File("scores.txt")); here we wrap a String so the example runs anywhere. Use .split(" ") to split 拆分 a line into parts and Integer.parseInt(...) to parse 解析 a number from text.

    Español

    Un Scanner lee texto línea por línea. Para un archivo real, se escribe new Scanner(new File("scores.txt")); aquí enmarcamos un String para que el ejemplo funcione en cualquier lugar. Use .split(" ") para dividir una línea en partes y Integer.parseInt(...) para analizar un número a partir de texto.

    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            // Real file:  Scanner in = new Scanner(new File("scores.txt"));
            String data = "Alice 80\nBob 95\nCara 72";
            Scanner in = new Scanner(data);
            int total = 0, count = 0;
            while (in.hasNextLine()) {
                String line = in.nextLine();
                String[] parts = line.split(" ");      // break the line on the space
                total += Integer.parseInt(parts[1]);
                count++;
            }
            System.out.println("average = " + (total / count));   // average = 82
        }
    }
    
    El Scanner lee líneas mientras hasNextLine es true
    El Scanner lee líneas mientras hasNextLine sea true
    12.2

    Tipos de preguntas del FRQ de AP

    English

    The AP CS A exam has four free-response 自由作答 questions, each a fixed shape:

    • Q1 — Methods & control: write methods to a given spec; loops, if, String/Math.
    • Q2 — Class design: write a full class (fields, constructor, methods) from a description.
    • Q3 — Array / ArrayList: process a 1-D array or ArrayList (search, count, build a new list).
    • Q4 — 2-D array: traverse a grid by row and column.

    The skill is always the same: read the spec, write the method exactly as described, return the right type.

    Common mistakes

    • nextInt() leaves the newline behind, so a following nextLine() reads an empty line — read it away first.
    • Check hasNext() before reading, to avoid running off the end of the file.
    • In the FRQ, read the method header carefully: match the return type and parameters exactly.
    Español

    El examen de AP CS A tiene cuatro preguntas de respuesta libre, cada una con una forma fija:

    • P1 — Métodos y control: escribir métodos según una especificación dada; bucles, if, String/Math.
    • P2 — Diseño de clases: escribir una clase completa (campos, constructor, métodos) a partir de una descripción.
    • P3 — Arreglo / ArrayList: procesar un arreglo 1-D o ArrayList (búsqueda, conteo, construir una nueva lista).
    • P4 — Arreglo 2-D: recorrer una cuadrícula por fila y columna.

    La habilidad siempre es la misma: leer la especificación, escribir el método exactamente como se describe y devolver el tipo correcto.

    public class Main {
        public static void main(String[] args) {
            // Q1 style: implement a method to a spec, then it is tested.
            System.out.println(countEven(new int[]{4, 7, 10, 3, 6}));   // 3
        }
    
        /** Returns how many values in arr are even. */
        public static int countEven(int[] arr) {
            int count = 0;
            for (int x : arr)
                if (x % 2 == 0) count++;
            return count;
        }
    }
    

    Errores comunes

    • nextInt() deja el salto de línea pendiente, por lo que un nextLine() posterior lee una línea vacía; léala primero para eliminarla.
    • Verifique hasNext() antes de leer, para evitar excederse al final del archivo.
    • En el FRQ, lea cuidadosamente el encabezado del método: coincida exactamente con el tipo de retorno y los parámetros.

Log in or create account · ⁨Iniciar sesión o crear cuenta⁩

IGCSE, A-Level & AP