Skip to content · ⁨コンテンツへスキップ⁩
Subjects · ⁨科目⁩
  • 1 Java basics · ⁨Javaの基礎⁩
    1.1

    クラス、メイン & 出力

    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 ;.
    日本語

    すべてのJavaプログラムはクラス内に存在する。それは main という名前のメソッドで始まる。 System.out.println(...) は改行付きでラインを出力し; System.out.print(...) は改行なしで出力する。

    public class Main {
        public static void main(String[] args) {
            System.out.println("Hello, world!");
            System.out.println("I am learning Java.");
        }
    }
    
    • Javaはコンパイルされる: コンパイラーが整個プログラムをチェックしてから実行する。
    • すべてのステートメントは半角カンマ ; で終わる。
    Java プログラムはクラス内にあり、main で開始されます
    Java プログラムはクラス内にあり、main で開始されます
    1.2

    変数 & プリミティブ型

    English

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

    日本語

    変数はその型を宣言しなければならない。一般的なプリミティブ型: int (整数), double (小数点付き数字), boolean (true/false), char (1文字)。

    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

    Comments & style

    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.
    日本語

    コメントは // (1行) または /* ... */ (ブロック) である。波括弧 { } の中のコードはインデントする。クラス名は大文字で始め、変数とメソッドはキャメルケース(小文字開始)を使用する。

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

    ** 一般的なミス **

    • すべてのステートメントは半角カンマ ; で終わる。
    • main は exactly public static void main(String[] args) でなければなりません。
    • println は新しいラインを追加します; print は追加しません。
  • 2 Operators & expressions · ⁨演算子と式⁩
    2.1

    Arithmetic & assignment

    English

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

    日本語

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

    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 truncates; involve a double for a real quotient
    int/int truncates; involve a double for a real quotient
    2.2

    Using objects: 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.
    日本語

    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").

    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() 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:

    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) 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.
    2.3

    Casting & type conversion

    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.
    日本語

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

    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
        }
    }
    

    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.
  • 3 Booleans & selection · ⁨ブール値と選択構造⁩
    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 { }.

    日本語

    if は条件が真のときにブロックを実行し、 else if と else はより多くのケースを追加する。条件は ( ) に、ブロックは { } に置く。

    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は真の分支を選択し、elseは偽の分支を選択
    ifは真の分支を選択し、elseは偽の分支を選択
    3.2

    論理演算子 & 比較

    English

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

    日本語

    ==、!=、<、>、<=、>= と比較すると、結果は boolean となる。&&(and)、||(or)、!(not)と組み合わせて論理演算子とする。String については .equals(...) を使用し、== は使わない。

    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.
    日本語

    switch は多数の固定値の中から選ぶ。各 case は break で終わります; default はフォールバックである。

    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");
            }
        }
    }
    

    ** 一般的なミス **

    • 条件は必ず boolean でなければならず、 if (x = 5) はコンパイルできない ( == を使用する)。
    • 各 switch ケースには break; が必要であり、そうでないと制御は次のケースにfall throughする。
    • && と || は論理演算子であり、 & と | はビット演算子である。
  • 4 Loops · ⁨ループ⁩
    4.1

    while ループ

    English

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

    日本語

    while ループは条件が真の間繰り返される。内部で何かを変化させない限り、無限ループとなる。

    public class Main {
        public static void main(String[] args) {
            int n = 1;
            while (n <= 3) {
                System.out.println(n);
                n++;
            }
        }
    }
    
    while ループは本体の各反復の前に条件をチェックします
    while ループは本体の各反復の前に条件をチェックします
    4.2

    for ループ

    English

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

    日本語

    for ループは初期化、条件、ステップを1行にまとめる。回数がわかっている場合に最適である。

    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

    蓄積

    English

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

    日本語

    アクセムレーターパターン: ループの前に変数を初期化し、毎回更新する。

    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

    ネストループ

    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.
    日本語

    ループ内のループはネストループである。外側のループの各反復ごとに内側のループが完全に実行される。

    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();
            }
        }
    }
    

    ** 一般的なミス **

    • for (int i = 0; i < n; i++) は n 回実行する (0 から n - 1); <= を使うと1回多く回る。
    • for (...) または while (...) の直後に半角カンマを置かない — 空のループになってしまう。
    • カウンターを for ヘッダー内で宣言し、そのスコープがループと一致するようにする。
  • 5 Strings · ⁨文字列⁩
    5.1

    String メソッド

    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:

    日本語

    String はテキストである。便利なメソッド: .length(), .charAt(i), .substring(a, b), .indexOf(x), .toUpperCase(), .equals(...) 。文字列は不変であり、各メソッドは 新しい 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
        }
    }
    

    毎日使うメソッド:

    メソッド 意味 例 → 結果
    .length() 文字数 "Hi".length() → 2
    .charAt(i) 1文字目 "Hi".charAt(0) → H
    .substring(a, b) 部分、 b より前に停止 "Python".substring(0, 3) → Pyt
    .substring(a) a から末尾まで "Python".substring(3) → hon
    .indexOf(x) 最初の位置、存在しない場合は -1 "banana".indexOf("na") → 2
    .equals(s) 同じテキスト? "hi".equals("hi") → true
    .compareTo(s) 順序: 負 / 0 / 正 "apple".compareTo("banana") → 負

    compareTo は辞書順で文字列を並べ替える — AP試験ではソート問題にこれを使う:

    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
    Key String methods: length, charAt, substring, equals
    5.2

    文字列の構築 & 走査

    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.
    日本語

    + (連結) で文字列をつなぐ。ループで各文字を訪問し .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
        }
    }
    

    ループで長いStringを構築する場合、 StringBuilder は遥かに速い: パーツをoonし、最後に .toString() を一度だけ呼び出す。

    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
        }
    }
    

    ** 一般的なミス **

    • 文字列は不変: s.toUpperCase() は新しいStringを返すので、結果を保存する。
    • s.charAt(i) で文字を読み取り、長さは s.length() (メソッドであり、 () を持つ)。
    • 大きなループで += を使って文字列を構築するのは遅い; StringBuilder を使うこと。
  • 6 Arrays · ⁨配列⁩
    6.1

    1次元配列

    English

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

    日本語

    配列は1つの型の固定個数の値を保持する。インデックスは 0 から始まり、 .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
        }
    }
    
    プリミティブは値そのものを持ち、配列変数は配列オブジェクトへの参照を持ちます
    プリミティブは値そのものを持ち、配列変数は配列オブジェクトへの参照を持ちます
    6.2

    配列アルゴリズム

    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.

    日本語

    ループで配列を巡回して最大値、合計、カウント、または検索を行います。for-eachループ(for (int x : a))は順に各値を読み取ります。

    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

    2次元配列

    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.
    日本語

    2次元配列は行と列のグリッドです: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
        }
    }
    

    ** 一般的なミス **

    • 配列のサイズは a.length です(角括弧や () は含みません)、作成時に固定されます。
    • 有効なインデックスは 0 から a.length - 1 で、a[a.length] を使用すると ArrayIndexOutOfBoundsException が発生します。
    • 新規の int[5] は空ではなくゼロで埋められます。
  • 7 ArrayList
    7.1

    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).

    日本語

    ArrayList は可変長リストであり、要素を追加または削除するたびに伸縮します。オブジェクトを格納するため、Integer (int ではない)のようなラッパー型を使用します。<Integer> の部分はジェネリックタイプです。主要なメソッド:.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
    ArrayList: 可変長リストにおける add, get, size
    7.2

    ArrayListのアルゴリズムと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.
    日本語

    .remove(i) はそれ以降のすべての要素を1つ左へシフトします。i で上向きにカウントしながら削除すると、次の要素をスキップしてしまいます。修正法:ループを逆方向に行うか、remove後に i を増減させないこと。

    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]
        }
    }
    

    ** 一般的なミス **

    • ArrayList は .size(), .get(i), .add(...) を使用し、配列で行う [] を使用しません。
    • インデックスによる前向きループ中に要素を削除すると、次の要素がスキップされます(removeのバグ)。ループを逆方向にするか、イテレータを使用してください。
    • プリミティブではなくオブジェクトを格納します:ArrayList<Integer> を使用し、Javaは int の値を自動ボックス化します。
  • 8 Writing classes · ⁨クラスの記述⁩
    8.1

    フィールド、コンストラクタ、メソッド

    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:

    日本語

    クラスはオブジェクトのための設計図です。フィールドはデータを格納し、コンストラクタは新しいオブジェクトを初期化し、メソッドは動作を表します。this.name は「このオブジェクトの name 」を意味します。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++;
        }
    }
    

    static メンバーは特定のオブジェクトではなくクラス自体に属します。クラス名に対してスタティックメソッドを呼び出します — Math.max のように — スティックフィールドはすべてのオブジェクト間で共有されます:

    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;
        }
    }
    
    フィールドは状態を格納;コンストラクタは構築;メソッドは実行
    フィールドは状態を格納;コンストラクタは構築;メソッドは実行
    8.2

    カプセル化

    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).
    日本語

    カプセル化とは、データを実装メソッドの裏に隠すことです。フィールドを private に指定して外部コードが直接アクセスできないようにし、読み出し用のアクセサ(getter)と安全に変更するためのメソッドを公開します。このメソッドはデータを守ることができ — この例では預入額は正である必要があります。

    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;
        }
    }
    

    ** 一般的なミス **

    • コンストラクタにはクラス名があり、返り値の型はありません(void でさえありません)。
    • 同名のパラメータと区別するために this.field を使用します。
    • フィールドを private にして、getter/setterメソッドを通じてアクセスします(カプセル化)。
  • 9 Inheritance & polymorphism · ⁨継承と多様性(ポリモフィズム)⁩
    9.1

    継承

    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(...).

    日本語

    継承によりサブクラスはスーパークラスを再利用できます。class Cat extends Animal を記述し、Cat は Animal のフィールドとメソッドを自動的に受け継ぎます。親のコンストラクタを 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とDogがAnimalを拡張:メンバーを継承して独自のものを追加
    CatとDogがAnimalを拡張:メンバーを継承して独自のものを追加
    9.2

    ポリモーフィズムと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.
    日本語

    サブクラスはメソッドをオーバーライドして親のバージョンを置き換えることができます。ポリモーフィズムとは、Shape 変数がどのサブタイプでも保持でき、Javaが実行時に適切な toString を選択することです。System.out.println(obj) は自動的に 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
    }
    

    ** 一般的なミス **

    • オーバーライドされたメソッドは签名を正確に一致させる必要があり、@Override を追加してコンパイラがミスに気づくようにします。
    • super(...) はサブクラスのコンストラクタの最初の行でなければなりません。
    • サブクラスのオブジェクトはスーパークラスのオブジェクトですが、その逆ではありません。
  • 10 Recursion · ⁨再帰⁩
    10.1

    Recursion

    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.
    日本語

    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.

    The call stack for factorial(3): each call waits, then returns in reverse order
    The call stack for factorial(3): each call waits, then returns in reverse order
    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)!
        }
    }
    

    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:

    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 归并排序 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.

    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];
        }
    }
    

    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.
  • 11 Searching & sorting · ⁨検索とソート⁩
    11.1

    線形探索と二分探索

    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.

    日本語

    線形探索はすべての要素を確認するため、どんな配列でも機能します。二分探索は遥かに高速ですが、ソート済みの配列が必要です:中央を見ることで、各ステップで半分を破棄します。両方ともインデックスを返しますが、見つけられない場合は -1 を返します。

    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;
        }
    }
    
    二分探索は各ステップで範囲を半分にするため、ソート済み配列の探索は O(log n)
    二分探索は各ステップで範囲を半分にするため、ソート済み配列の探索は O(log n)
    11.2

    セレクションソートと挿入ソート

    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.
    日本語

    セレクションソートは残りの最小値を繰り返し見つけて先頭に交換します。挿入ソートは各値を取り出して、既にソート済みの値の間で正しい位置にスライドさせて挿入します。

    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]
        }
    }
    

    速度比較:

    アルゴリズム 時間
    線形探索 O(n)
    二分探索 O(log n)、ソート済み配列のみ
    セレクション/挿入ソート O(n²)
    マージソート (トピック10) O(n log n)

    ** 一般的なミス **

    • 二分探索はソート済みの配列でのみ機能します。
    • 線形探索は O(n)、二分探索は O(log n) ですが、事前にソートする必要があります。
    • セレクションソートと挿入ソートは O(n²) で、理解しやすいものの、大規模データでは遅いです。
  • 12 Files & the FRQ · ⁨ファイルとFRQ(自由回答問題)⁩
    12.1

    Text files with 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.

    日本語

    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.

    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
        }
    }
    
    Scanner reads lines while hasNextLine is true
    Scanner reads lines while hasNextLine is true
    12.2

    The AP FRQ question types

    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.
    日本語

    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.

    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;
        }
    }
    

    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.

Log in or create account · ⁨ログインまたはアカウント作成⁩

IGCSE, A-Level & AP