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 程序都住在一个类(class)里面。它从一个叫 main 的方法(method)开始。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 是编译(compile)型的:编译器(compiler)先检查整个程序,然后才运行。
每条语句(statement)都以分号 ; 结尾。
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).
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
注释与风格
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).
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 会截断;涉及 double 以获得实数商
2.2
使用对象:String、Math、包装类
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.
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() 返回一个随机整数 double,范围为 0.0 到(但不包括)1.0。对其进行缩放并强制类型转换以获得整数——这是 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)和 Integer.MIN_VALUE 是 int 的上下限;超过就会绕回(溢出)。
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
}
}
if runs a block when a condition 条件 is true; else if and else add more cases. The condition goes in ( ), the block in { }.
中文
if 在条件(condition)为真时运行一个块;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 选择假分支
3.2
逻辑运算符与比较
English
Compare with ==, !=, <, >, <=, >= — a comparison 比较 gives a boolean. Combine with && (and), || (or), ! (not) — the logical operators 逻辑运算符. For Strings, use .equals(...), not==.
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");
}
}
}
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 在每次循环体执行前检查条件
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 循环把"开始、条件、步进"打包在一行里。当你知道次数时最适合用它。
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.
中文
累加器(accumulator)模式:在循环之前先建一个变量,然后每一轮更新它。
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);用 <= 会多跑一次。
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:
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)
取一个字符
"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 在前)
System.out.println(a.compareTo("apple")); // 0 (相等)
}
}
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
}
}
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
}
}
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
二维数组
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-D array)是由行和列组成的网格(grid):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
}
}
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).
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
7.2
ArrayList 算法与删除陷阱
English
.remove(i) shifts 移动 every later element one place left. If you remove while counting iup, 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) 会把后面的每个元素向左移动(shift)一位。如果你一边让 i递增一边删除,就会跳过下一个元素。解决办法:倒着循环,或删除后不要让 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);
// 删除所有的 4 —— 倒着循环,这样删除时不会跳过元素。
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 bug)。要么倒着遍历,要么用迭代器。
存的是对象而非基本类型:用 ArrayList<Integer>,Java 会自动把 int 装箱。
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:
中文
类(class)是对象的蓝图。它的字段(field)存储数据,构造方法(constructor)初始化一个新对象,方法(method)是它能做的动作。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) { // 构造方法
this.name = name;
this.age = age;
}
public String describe() {
return name + " is " + age + " years old";
}
public void haveBirthday() {
age++;
}
}
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; // 被所有 Counter 对象共享
public Counter() { count++; }
public static int made() { // 用类名调用:Counter.made()
return count;
}
}
Fields store state; constructor builds; methods act
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).
public class Main {
public static void main(String[] args) {
Account a = new Account(100);
a.deposit(50);
a.deposit(-999); // 被守护条件拒绝
System.out.println(a.getBalance()); // 150
}
}
class Account {
private int balance; // 对外隐藏
public Account(int start) {
balance = start;
}
public void deposit(int amount) {
if (amount > 0) balance += amount; // 守护条件保持余额有效
}
public int getBalance() { // 访问方法(getter)
return balance;
}
}
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(...).
中文
继承(inheritance)让子类(subclass)复用父类(superclass)。写 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 (从 Animal 继承而来)
c.speak(); // Meow (Cat 自己的方法)
}
}
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); } // 调用 Animal 的构造方法
public void speak() { System.out.println("Meow"); }
}
Cat 和 Dog 都 extends 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.
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.
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; // 基准情形
return n * factorial(n - 1); // 递归调用:n * (n-1)!
}
}
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.
public class Main {
public static void main(String[] args) {
int[] a = {2, 5, 8, 12, 16, 23}; // 已排序,所以二分查找可用
System.out.println(linear(a, 12)); // 3
System.out.println(binary(a, 12)); // 3
System.out.println(binary(a, 9)); // -1 (未找到)
}
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)
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; // 交换到位
}
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) { // 把较大的值向右移
a[j + 1] = a[j];
j--;
}
a[j + 1] = key; // 把 key 放进空位
}
System.out.println(Arrays.toString(a)); // [1, 2, 5, 7, 9]
}
}
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) {
// 真实文件: 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(" "); // 按空格拆分
total += Integer.parseInt(parts[1]);
count++;
}
System.out.println("average = " + (total / count)); // average = 82
}
}
Scanner reads lines while hasNextLine is true
12.2
AP FRQ 题型
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.