AP CSA 抱佛脚专用

Where I died

  • 【与 C++ 不一样】不是 bool,是 boolean
  • 类内的属性前最好加一个 private
  • 【与 C++ 不一样】创建新对象时需要 new
    • e.g. 2021 Q3
    • NO memberList.add(MemberInfo(name, gradYear, true));
    • YES memberList.add(new MemberInfo(name, gradYear, true));
  • 【与 C++ 不一样】ArrayList 的访问要用 get,修改要用 set
  • Math 应该不可用
  • 非原生类型比较要用 equals
    • String 也是

Enhanced For-Loop

Example 0 - ArrayList.add (Diag #3)

// list 是一个 ArrayList<Integer>
for (Integer num : list) {
    if (/* condition */)
        list.add(0);
}

这个程序更改了 ArrayList 的长度,抛出 ConcurrentModificationException

类似 C++ 中的迭代器机制,乱动容器会让迭代器寄掉。

顺便说一下,修改 num 的值不会报错,也不会修改到 list 中的元素。这点和 C++ 也一样。

Example 1 - int[] (Prac 2 #6)

for (int[] row : mat)
    for (int num : row)
        num = 100;

这段代码不会报错,但是也不能起到赋值的作用。事实上这段代码除了语法正确以外没有任何意义。

num = 100; 仅仅会修改局部变量 num 的值,不会修改 mat 中的元素。

Example 2 - Myclass[] (Prac 1 #14)

for (Clock[] row : allClocks)
    for (Clock c : row) {
        System.out.print(c); // I
        c.setTime(0, 0, 0); // II
        c = new Clock(0, 0, 0); // III
    }

I 和 II 和 III 都不会报错,但是 I 和 II 会按预想方式运行。
III 修改了局部变量 c 的引用,不会更改 allClocks 中的 Clock 元素。

Subclass

Example 0 - 并非动态绑定 (Prac 1 #31)

ThreeDigitInteger 是一个 class,有一个子类叫 ThreeDigitCode。

ThreeDigitCode 有一个 ThreeDigitInteger 没有的方法,叫做 isValid。
ThreeDigitInteger code = new ThreeDigitCode(127); // I
ThreeDigitInteger num = new ThreeDigitInteger(456); // II
ThreeDigitCode newCode = new ThreeDigitCode(241); // III

只有 III 不会报错。

做编译期检查的时候就会发现不对了。前两个是 ThreeDigitInteger,不能用只有子类有的 isValid,报 CE。

Example 1 - 父类中的动态绑定 (Prac 2 #16)

public class Main {
    public static void main(String[] args) {
        Performer p = new Singer();
        p.act();
    }
}

class Performer {
    public void act() {
        System.out.print(" bow");
        perform();
    }
    public void perform() {
        System.out.print(" act");
    }
}

class Singer extends Performer {
    public void act() {
        System.out.print(" rise");
        super.act();
        System.out.print(" encore");
    }

    public void perform() {
        System.out.print(" aria");
    }
}

Performer p = new Signer(); p.act(); 的输出是?


输出 rise bow aria encore

  1. 首先 p 虽然是个 Performer 但是其实是个 Singer 对象,所以调用 act 时根据动态绑定,进 Singeract,输出 rise
  2. super.act() 调用 Performeract。输出 bow
  3. Performeract 中的 perform 根据动态绑定调用 Singerperform。输出 aria
  4. 回到第一步,输出 encore

Example 2 - 方法参数的类型兼容性 (Prac 2 #37)

TennisPlayer 类有一个子类 WeakPlayer,WeakPlayer 类有一个子类 Beginner。
public static void giveEncouragement(WeakPlayer t) {
    /* implementation not shown */
}
public static void main(String[] args) {
    TennisPlayer w = new WeakPlayer();
    TennisPlayer b = new Beginner();
    Beginner bp = new Beginner();

    giveEncouragement(w); // I
    giveEncouragement(b); // II
    giveEncouragement(bp); // III
}

类似于 Example 0,I 和 II 报 CE。

Binary Search

默认分为 \([l,mid]\)\([mid+1,r]\),当题目给出具体代码时有可能是 \([l,mid-1]\)\([mid+1,r]\)

最坏情况的迭代次数是 \(\lceil \log_2 n \rceil + 1\)

杂项

  • StringcompareTo 遇到两字符串长度不同时,可以看作将短的那个后面补 \(0\)
  • Integer 大部分情况可以当 int 用,除了 == 必须用 .equals。不等号是没有问题的,因为会自动拆包。
  • ArrayList 有内置的 toString,格式与 Python 的 list 一样。
  • super 必须出现在子类构造方法的第一句。
    • 不写 super 需要父类有无参构造方法,会自动调用。
posted @ 2025-05-06 22:17  August_Light  阅读(18)  评论(0)    收藏  举报