You are on page 1of 67

APCS_MCQ 知识点总结

一.Java 除法,强制转换等
1. Java 除法:
int / int => int (去掉小数部分)
double / int = > double(正常运算)
int / double = > double(正常运算)
double / double => double(正常运算)
注意:在 java 中只要涉及 double 的运算,由于小数位数有限,就会出现 round-off error(四舍五入差值)

2. double 和 int 之间的赋值:


double 值/变量不可赋值给 int 变量, 报错!
int 值/变量可赋值给 double 变量,double 变量自动加.0
double b = 6.0;
int a = 5;
b = 5; //ok,b 自动变 5.0
b = a; //ok,b 自动变 5.0
int a = b; //Error!
int a = 5.0; //Error!

3.double 和 int 之间强制转换:


强制转换格式(type)变量
注意(type)(Expression)这种情况先算 expression,结果才强转 int,所以需要 int/int 得到 double
结果时,需要(double)int/int 格式!
double 数值强转为 int 舍弃小数部分,int 数值强转 double 自动加.0
(int) 6.5 => 6 (double) 5/ 4 => 1.25 double(5/4) => 1.0
例:1. In the code segment below, assume that the int variables a and b have been properly declared and initialized.
int c = a;
int d = b;
c += 3;
d--;
double num = c;
num /= d;
Which of the following best describes the behavior of the code segment?
(A) The code segment stores the value of (a + 3) / b in the variable num.
(B) The code segment stores the value of (a + 3) / (b - 1) in the variable num.
(C) The code segment stores the value of (a + 3) / (b - 2) in the variable num.
(D) The code segment stores the value of (a + 3) / (1 - b) in the variable num.
(E) The code segment causes a runtime error in the last line of code because num is type double and d is
type int.
答案:(B) double num 被 int c 赋值,可。num/ = d 相当于 num = num/d; double = double/int 可。
2. Consider the following code segment, which is intended to find the average of two positive integers, x and y.
int x;
int y;
int sum = x + y;
double average = (double) (sum / 2);
Which of the following best describes the error, if any, in the code segment?
(A) There is no error, and the code works as intended.
(B) In the expression (double) (sum / 2), the cast to double is applied too late, so the average
will be less than the expected result for even values of sum.
(C) In the expression (double) (sum / 2), the cast to double is applied too late, so the average
will be greater than the expected result for even values of sum.
(D) In the expression (double) (sum / 2), the cast to double is applied too late, so the average
will be less than the expected result for odd values of sum.
(E) In the expression (double) (sum / 2), the cast to double is applied too late, so the average
will be greater than the expected result for odd values of sum.
答案:D (double) (sum / 2)先算(sum/2) sum 是 int 所以先算 int/int 小数部分已舍弃再强转为 double,too late.
正确格式为(double)sum/2
3. Consider the following code segment, which is intended to print the digits of the two-digit int number num in reverse
order. For example, if num has the value 75, the code segment should print 57. Assume that num has been properly
declared and initialized.
/* missing code */
System.out.print(onesDigit);
System.out.print(tensDigit);
Which of the following can be used to replace /* missing code */ so that the code segment works as intended?
(A) int onesDigit = num % 10;
int tensDigit = num / 10;

(B) int onesDigit = num / 10;


int tensDigit = num % 10;

(C) int onesDigit = 10 / num;


int tensDigit = 10 % num;

(D) int onesDigit = num % 100;


int tensDigit = num / 100;

(E) int onesDigit = num / 100;


int tensDigit = num % 100;
答案: A 求一个数的个位数就是%10,去掉个位数/10
4. Consider the following code segment.
double a = 1.1;
double b = 1.2;
if ((a + b) * (a - b) != (a * a) - (b * b)) {
System.out.println("Mathematical error!");
}
Which of the following best describes why the phrase "Mathematical error!" would be printed?
(Remember that mathematically (a + b) * (a - b) = a2 - b2 .)
(A) Precedence rules make the if condition true.
(B) Associativity rules make the if condition true.
(C) Roundoff error makes the if condition true.
(D) Overflow makes the if condition true.
(E) A compiler bug or hardware error has occurred.
答案:C double 运算由于 java 小数位限制问题会产生四舍五入的 roundoff error A 优先级 B 结合性原则 D 内存
溢出
5. The following code segment is intended to round val to the nearest integer and print the result.
double val = -0.7;
int roundedVal = (int) (val + 0.5);
System.out.println(roundedVal);
Which of the following best describes the behavior of the code segment?
(A) The code segment works as intended.
(B) The code segment does not work as intended because val and roundedVal should be declared as
the same data type.
(C) The code segment does not work as intended because the expression (val + 0.5) should be cast to
a double instead of an int.
(D) The code segment does not work as intended because val should be cast to an int before 0.5 is
added to it.
(E) The code segment does not work as intended because the expression (int) (val + 0.5) rounds
to the nearest integer only when val is positive.
答案: E 因为 val 为负数时, 比如-1.7 roundVal 是-1.2 答案-1 是错的, 只有在 val 为正数时, 不管 val 时<n.5 n.5+0.5
round to n 还是>n.5 n.5+0.5 round to n+1 结果都是对的
二.Boolean 式,优先级问题

true && true = true true | | true = true


true && false = false true | | false = false
false && true = false false | | true = false
false && false = false false | | false = false

A && true = A
A || false = A

A ||(B&&C) => (A||B) && (A||C)


A && (B || C) => (A && B) || ( A && C)
! ( A && B) => ! A | | !B
! ( A | | B) => ! A && !B

优先级别: () > ! > +/- > ==/!= > && > ||

例:6. Assume that a, b, c, and d have been declared and initialized with int values.
!((a >= b) && !(c < d))
Which of the following is equivalent to the expression above?
(A) (a < b) || (c < d)
(B) (a < b) || (c >= d)
(C) (a < b) && (c < d)
(D) (a >= b) || (c < d)
(E) (a >= b) && (c < d)
答案:A 此题要仔细分清楚大括号的范围 !((a >= b) && !(c < d)) 相当于 !(A && B)其中 A 为 (a >=
b) , B 为 !(c < d) 拆分后 !(A && B) => !A||!B, !A 为 a<b, !B 为 c<d,所以最终结果为 A
7. Assume that a and b are variables of type int. The expression
!(a < b) && !(a > b)
is equivalent to which of the following?
(A) true
(B) false
(C) a == b
(D) a != b
(E) !(a < b) && (a > b)
答案:C 思路 1: 优先级 !>& 所以!(a < b)和!(a > b) 先算,之后再&,!(a < b)=> a>=b ,
!(a > b) => a <= b,整个式子相当于(a>=b)&&(a<=b)这个式子只有在 a==b 时为 true a!=b 时为 false 所以它
等同于 a==b
8. Assume that the boolean variables a and b have been declared and initialized. Consider the following expression.
(a && (b || !a)) == a && b
Which of the following best describes the conditions under which the expression will evaluate to true?
(A) Only when a is true
(B) Only when b is true
(C) Only when both a and b are true
(D) The expression will never evaluate to true.
(E) The expression will always evaluate to true.
答案:B boolean 式题目天花板级别。首先()优先界最高,左边()部分先看成整体,==优先级别高于&& 所
以先算()式==a 的结果再 &&b
(a && (b || !a))是 A&&(B||C)式子转换为(A&&B)||(A&&C) => (a&&b)||(a&&!a)=> a&&!a 即为 false,所以式子变
为 (a&&b)||false,A||false==>A,所以式子相当于(a&&b),
左边(a && (b || !a))式子最终转换结果为 a&&b 接下来是(a&&b)==a && b, 相当于((a&&b)==a )&& b
题目问这个式子什么时候为 true,所以首先 b 要为 true,然后检验 b 为 true 时(a&&b)==a 是否也为 true,b 为 true 时此式
子变为 a == a 为 true,所以只有 b 为 true 时整个式子为 true。
假设此题 b 为 true 时((a&&b)==a )是其他推导结果为 false 的式子,则整个式子永远为 false

三.if else 选择结构


1. if else 结构
if(A)
{...}
else{... } 注意: else 不需要带任何条件且 else 条件默认为且一定为 !A
2. if 嵌套结构
if(A)
{
if(B)
{
statement C;
}
else
{
Statement D;
}
}
else
{
statement E;
}
注意:statement C 执行条件为 A&&B,statement B 执行条件为 A&!B,statement E 执行条件为 !A
3.if if 并列结构(注意 statement 中是否有 return 语句)
a. if if 并列结构中 statement 均不包含 return 语句
if(A)
{
statement A;
}
if(B)
{
statement B;
}
if(C)
{
statement C;
}
这种结构不包含 return 语句,所有 if 条件顺序执行,如果满足 A 条件的也满足 B 条件,则 statementA 的执行结果会被
statementB 覆盖,如果继续仍满足 C 条件,则最终结果被 statementC 覆盖。
但是如果刚好条件覆盖满足原题目要求,并列 if 结构未必都是不符合题意的

28. The price per box of ink pens advertised in an office supply catalog is based on the number of boxes ordered.The
following table shows the pricing.

The following incomplete method is intended to return the total cost of an order based on the value of the
parameter numBoxes.
Which of the following code segments can be used to replace /* missing code */ so that method getCost will work
as intended?

(A) I only
(B) II only
(C) III only
(D) I and II
(E) II and III
III if 和 else 一定是互斥的所以 if (numBoxs > 0)的 elseif 条件默认先满足 numBox<=0, numBoxes 就不可能再>=5
I if(num>10)的一定满足 if(num>=5)一定满足(num>0)所以 num>10 的最终结果会被 num>0 覆盖,并不是 num>10
真正结果 同理 num>=5 也是被 num>0 覆盖
但是如果 I 改成
if(numBox > 0)
{
totalCost = numBoxes * 5.0;
}
if(numBox > 5)
{
totalCost = numBoxes * 3.0;
}
if(numBox > 10)
{
totalCost = numBoxes * 1.5;
}
就还是对的,因为 numBox>0 的但是小于 5 的无法走 if(numBox>5)的条件,还是相当于 numBoxs >0
& numBoxs < 5, 然后 numBox >5 的虽然走了 num>0 的条件,但是还是会走 num>5,最终是 num>5 的结果,所以
没问题。
b. if if 并列结构中 statement 均包含 return 语句
if(A)
{
statement A;
return XXX;
}
if(B)
{
statement B;
return XXX;
}
if(C)
{
statement C;
return XXX;
}
这种结构每个 if 条件均包含 return 语句,return 语句立刻结束函数,所以如果满足条件 A,直接 return 不会再走
statementB,如果可以走 statementB,说明条件满足 !A&&B,同理如果满足!A&&B,不会走 C 直接 return 结束函
数,如果满足!A&&!B&&C 则可以走到 statementC
所以此 if 结构等同于
if(A)
{
statement A;
return XXX;
}
else if(B)
{
statement B;
return XXX;
}
else if(C)
{
statement C;
return XXX;
}
例:9. Consider the following incomplete method.
public int someProcess (int n)
{
/* body of someProcess */
}
The following table shows several examples of input values and the results that should be produced by calling
someProcess .

3 30
6 60
7 7
8 80
9 90
11 11
12 120
14 14
16 160
which of the following code segments could be used to replace /* body of someProcess */ so that the method
will produce the results shown in the table?
I. if ( (n % 3 == 0) && (n % 4 == 0))
return n * 10;
else
return n;

II. if ( (n % 3 == 0) | | (n % 4 == 0))
return n * 10;
return n;

III. if (n % 3 == 0)
if (n % 4 == 0)
return n * 10;
return n;
(A) I only
(B) II only
(C) III only
(D) I and III
(E) II and III
答案:B n % 3 == 0 的数,即为 3 的倍数,此题中 3,6,8,9,12,16 等被 3 或 4 整除的数,结果是参数*10, 其他情
况结果为参数值本身,所以选 II,
III if 嵌套 if 相当于 (n % 3 == 0) && (n % 4 == 0)又因为 statement 中包含 return 所以 I 和 III 其实相同
10. Consider the following instance variables and method that appear in a class representing student information.

private int assignmentsCompleted;


private double testAverage;
public boolean isPassing ()
{ /* implementation not shown */ }
A student can pass a programming course if at least one of the following conditions is met.

• The student has a test average that is greater than or equal to 90.
• The student has a test average that is greater than or equal to 75 and has at least 4 completed
assignments. Consider the following proposed implementations of the isPassing method.

I. if (testAverage >= 90)


return true;
if (testAverage >= 75 && assignmentsCompleted >= 4)
return true;
return false;

II. boolean pass = false;


if (testAverage >= 90)
pass = true;
if (testAverage >= 75 && assignmentsCompleted >= 4)
pass = true;
return pass;

III. return (testAverage >= 90)


| | (testAverage >= 75 && assignmentsCompleted >= 4);

Which of the implementations will correctly implement method isPassing?

(A) I only
(B) II only
(C) I and III only
(D) II and III only
(E) I, II, and III
答案 E 第一个如果 testAverage>=90 立刻 return 结束函数可以,如果不满足 testAverage>=90 走第二个 if 如果
满足条件 testAverage >= 75 && assignmentsCompleted >= 4 就返回 true,都不满足就返回 false
第二个并列 if 也包含了两种情况都可以返回 true,没问题
第三题是两个条件至少满足其一就 true 所以是||没问题
11. Consider the following code segment, which is intended to simulate a random process. The code is intended to set the
value of the variable event to exactly one of the values 1, 2, or 3, depending on the probability of an event occurring.
The value of event should be set to 1 if the probability is 70 percent or less. The value of event should be set to 2 if
the probability is greater than 70 percent but no more than 80 percent. The value of event should be set to 3 if the
probability is greater than 80 percent. The variable randomNumber is used to simulate the probability of the event
occurring.
int event = 0;
if (randomNumber <= 0.70)
{
event = 1;
}
if (randomNumber <= 0.80)
{
event = 2;
}
else
{
event = 3;
}

The code does not work as intended. Assume that the variable randomNumber has been properly declared and
initialized. Which of the following initializations for randomNumber will demonstrate that the code segment
will not work as intended?
(A) randomNumber = 0.70;
(B) randomNumber = 0.80;
(C) randomNumber = 0.85;
(D) randomNumber = 0.90;
(E) randomNumber = 1.00;
答案 A 这题因为小于 7.0 的也一定满足小于 8.0,所以满足 7.0 的结果被 8.0 覆盖,所以所有<7.0 分数的都
不对。选 A
四、for_loop,while_loop
1. 循环一维数组或 arrayList 时注意边界,注意递增变化
若出现 arr[i-1], int i =1 开始,若出现 arr[i+1], i < length-1
循环的递增变化有时非 i++,而是 i = i+2 等
例:14. Consider the following method, which is intended to return the number of local maximum values in an array. Local
maximum values are array elements that are greater than both adjacent array elements. The first and last elements of
an array have only a single adjacent element, so neither the first nor the last array element is counted by this
method.For example, an array containing the values {3, 9, 7, 4, 10, 12, 3, 8} has two local maximum values:
9 and 12.
public static int countPeaks (int [] data){
int numPeaks = 0;
for ( /* missing loop header */ )
{
if( data[i] > data[i-1] && data[i] > data[i+1])
{
numPeaks++;
}
}
return numPeaks;
}
Which of the following can replace /* missing loop header */ so the method countPeaks works as intended?
(A) int p = data.length - 1; p > 0; p--
(B) int p = 0; p < data.length; p++
(C) int p = 0; p < data.length - 1; p++
(D) int p = 1; p < data.length; p++
(E) int p = 1; p < data.length - 1; p++
答案:E
2 双重 for 循环
双重 for 循环注意外层循环执行一次,内层循环执行一轮
打印内容等,先按照内层循环开始执行,然后是外层代码,
例:a. 二维数组 row-major 打印元素时列号递增,打印一行后,行号递增,所以列递增写在内层循环,行递
增写在外层循环。且先按照内存循环的递增情况执行代码!然后再按照外层循环执行
b.双重 for 循环打印三角形等,外层循环决定行数,内层循环决定每一行打印的内容
考题类型: 1 循环执行次数,2 循环执行结果,打印图形等 3 外层/内层循环代码改变对循环次数的影响。
例:15. Consider the following code segment.
int outerMax = 10;
int innerMax = 5;
for (int outer = 0; outer < outerMax; outer++){
for (int inner = 0; inner <= innerMax; inner++)
{
System.out.println (outer + inner);
}
}
How many values will be printed when the code segment is executed?
(A) 45
(B) 50
(C) 55
(D) 60
(E) 66
答案:D 执行次数外层 10 次内层 6 次,所以总次数 60
16. Consider the following method.
public int sol (int lim)
{
int s = 0;
for (int outer = 1; outer <= lim; outer++)
{
for (int inner = outer; inner <= lim; inner++)
{
s++;
}
}
return s;
}
What value is returned as a result of the call sol(10)?
(A) 20
(B) 45
(C) 55
(D) 100
(E) 385
答案:C 外层 loop1,inner 执行 1-10,10 次,loop2,inner 执行 2-10,9 次。。。Loop10,inner 执行 1 次所以
最终次数为 1+2+3...+10 答案是 C
17. The question refer to the following code segment.
int k = a random number such that 1 ≤ k ≤ n ;
for(int p = 2; p <= k; p++)
for(int r = 1; r < k; r++)
System.out.println("Hello");
What is the maximum number of times that Hello will be printed?
(A) 2
(B) n - 1
(C) n - 2
(D) (n - 1)2
(E) n2
答案:D,最大次数就是 k = n 的时候,所以外层是 2-n,一共 n-1 此,内层 1 到 n-1 也是 n-1 次,所以答案是 D
18. The question refer to the following code segment.
int k = a random number such that 1 ≤ k ≤ n ;
for(int p = 2; p <= k; p++)
for(int r = 1; r < k; r++)
System.out.println("Hello");
What is the minimum number of times that Hello will be printed?
(A) 0
(B) 1
(C) 2
(D) n - 1
(E) n - 2
答案:答案 A 如果 k=1 外层不会执行
19. Consider the following output.
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
Which of the following code segments will produce the output shown above?
(A) for(int j = 1;j <= 6; j++)
{
for (int k = 1; k < j; k++)
System.out.print(" " + k);
System.out.println();
}
(B) for(int j = 1;j <=6;j++)
{
for (int k = 1; k <= j; k++)
System.out.print(" " + j);
System.out.println();
}
(C) for( int j = 1; j <=6;j++)
{
for (int k = 1; k <= j; k++)
System.out.print(" " + k);
System.out.println();
}
(D) for( int j = 1; j< 6; j++)
{
for (int k = 1; k <= j; k++)
System.out.print(" " + k);
System.out.println();
}
(E) for( int j = 1; j< 6;j++)
{
for (int k = 1; k < j; k++)
System.out.print(" " + k);
System.out.println();
}
答案:C 这种题型,外层循环决定最终结果的行数,内层循环决定每行打印的内容。最终结果是 6 行,所以外
层循环 6 次,内层循环次数从 1 到 6 递增,所以内层循环参数的变化一定和外层循环有关,这时检查代码的内层
循环的最小值和最大值是否满足第一次循环是 1 最后一次是 6 即可。此时 BC 都满足条件,还要具体看内层循环
打印的是外层参数还是内层参数,因为打印结果是123递增所以打印的是内层变化值。所以此题选 C
只要出现三角形,内层循环变化的参数一定和外层相关。

for(int j = 1;j <=6;j++)


{
for (int k = 1; k <= j; k++)
System.out.print(" " + j);
System.out.println();
}
打印结果:
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
6 6 6 6 6 6

for(int j = 1;j <=6;j++)


{
for (int k = j; k <=6 ; k++)
System.out.print(" " + k);
System.out.println();
}
打印结果:
1 2 3 4 5 6
2 3 4 5 6
3 4 5 6
4 5 6
5 6
6
for(int j = 1;j <=6;j++)
{
for (int k = j; k <= 6 ; k++)
System.out.print(" " + j);
System.out.println();
}
打印结果:
1 1 1 1 1 1
2 2 2 2 2
3 3 3 3
4 4 4
5 5
6
3.Enhanced for 格式
注意 enhanced for 格式 :左边的变量永远代表的是值,如果把它放在[k] get(k)这些位置,一定是错的!!!
还有不可以通过冒号左边的变量真正的改变数组中元素的值!左边的变量值会变,但是数组中元素的值不会真的
跟着改变(见例题 22)
A.一维数组:
For ( type 变量名 : 一维数组) 变量即依次代表一维数组中的所有值

int[] nums = { 1, 2, 3};


for( int i : nums) { System.out.print( “ “ + i); } //output: 1 2 3
B.二维数组:
For ( type[] 一维数组名:二维数组) //一维数组名依次代表二维数组中的每一行
{
For ( type 变量名:一维数组名同上)//变量代表二位数组每行的所有元素

int[][] nums = {{ 1, 2, 3}, {2,3,4}};


for( int[] row : nums){ //row is nums[0], nums[1]
for( int num : row){ System.out.print( “ “ + i); } //output: 1 2 3 2 3 4

C.ArrayList:
For ( type(有时是 class 名) 变量名:list 名)
{
变量名.method()
}

ArrayList:
ArrayList < ClassName> list;
for( ClassName obj : list)
{
obj.ClassMethod(); // obj is list.get(i)
}

例题:
20. Consider the following incomplete method, which is intended to return the sum of all the elements in its
array parameter.

/**Precondition:data.length 0*/
public static int total(int[] data)
{
int result = 0;

/* missing code */

return result;
}
The following code segments have been proposed to replace /* missing code */.

I. for (int k = 0; k < data.length; k++)


{
result += k;
}
II. for (int d : data)
{
result += d;
}
III. for (int k = 0; k < data.length; k++)
{
result += data[k];
}

Which of the replacements for /* missing code */ could be used so that total will work as intended?
(A) I only
(B) II only
(C) III only
(D) I and II
(E) II and III
答案:E,enhanced for 最常见题型,I 不对是因为加的是 index

21. Consider the following method.


public static void addOneToEverything(int[] numbers)
{
for (int j = 0; j < numbers.length; j++)
{
numbers[j]++;
}
}
Which of the following code segments, if any, can be used to replace the body of the method so that
numbers will contain the same values?
I.
for (int num : numbers)
{
num++;
}
II.
for (int num : numbers)
{
num[j]++;
}
III.
for (int num : numbers)
{
numbers[num]++;
}
(A) I only
(B) I and III only
(C) II and III only
(D) I, II, and III
(E) None of the code segments will return an equivalent result.
答案:E II num 不是数组格式错误,III num 永远不可以放在[]里 I 不可以用 num 真正改变数组中的值

22. Consider the following code segment.


int[] arr = {4, 2, 9, 7, 3};
for (int k : arr)
{
k = k + 10;
System.out.print(k + " ");
}
for (int k : arr)
System.out.print(k + " ");
What is printed as a result of executing the code segment?
(A) 0 1 2 3 4 0 1 2 3 4
(B) 4 2 9 7 3 4 2 9 7 3
(C) 10 11 12 13 14 0 1 2 3 4
(D) 14 12 19 17 13 4 2 9 7 3
(E) 14 12 19 17 13 14 12 19 17 13
答案:D,k 依次代表一维数组中的每个值,k = k+10 可以改变 k 的值,但是并不能通过 k 改变一维数组的中的元素的
值,所以在第二次循环打印 k 值的时候,数组值未变。答案是 D

23.Consider the following class definition.


public class Book
{
private int pages;
public int getPages()
{
return pages;
}
// There may be instance variables, constructors, and methods not shown.
}

The following code segment is intended to store in maxPages the greatest number of pages found in any Book
object in the array bookArr.

Book[] bookArr = { /* initial values not shown */ };


int maxPages = bookArr[0].getPages();
for (Book b : bookArr)
{
/* missing code */
}

Which of the following can replace /* missing code */ so the code segment works as intended?

答案:B. bookArr 是一个对象型的一位数组,


所以每个元素都是一个 object,b 就带边数组中的每个 object 可以调用 Book
Class 中的函数 getPages()
五. 一维数组
常考题型如下:
1. 遍历时边界问题
若出现 arr[i-1], int i =1 开始,若出现 arr[i+1], i < length-1

2.一维数组 new 之后所有值都是默认值


即 int[] arr = new int[5]; //arr 中所有值都是 0
Boolean[] arr = new boolean[5]; //arr 中所有值都是 false
Double[] arr = new double[5]; //arr 中所有值都是 0.0
String[] arr = new String[5]; //String 型一维数组,数组中的每个元素都是一个 string 变量,默认所有
值都是 null
Cat[] arr = new Cat[5]; //object 型一维数组,数组中的每个元素都是 class 类型的一个 object,初始
默认值都是 null,填充具体值后,都可以调用 class 中的 method
3.一维数组作为函数参数传入可改变数组内容
因为一维数组作为参数传入 method 时,传入的一维数组在内存中的起始位置,函数内容中对一维数组中的值进
行操作是根据其实位置寻找其对应 index,并直接更改该内存位置的值,所以一维数组作为参数传入 method,在
函数结束后其内容也相应更改。
但是要注意有一种题目,函数外一维数组 arr[]传入函数赋值给参数 list[]后,list[]重新 new 了一个新的一维数组
就不再和传入 arr[]指向相同位置,此时函数中 list[]改变并不能影响函数外 arr[]的值(见题 25)
例:24. Consider the following method.

following code segment appears in another method in the same class.

What is printed as a result of executing the code segment?


(A) 5 2 1 3 8
(B) 5 7 3 4 11
(C) 5 7 8 11 19
(D) 7 3 4 11 8
(E) Nothing is printed because an ArrayIndexOutOfBoundsException is thrown during the execution of method
mystery.
答案:C 此题需要注意data[1] = data[0]+data[1] =>7,在计算data[2] = data[1]+data[2]时要用已经改变了的data[1]
7去计算而不是2.
25.Consider the following two methods that appear within a single class.

public void changeIt(int[] list, int num)


{
list = new int[5];
num = 0;
for (int x = 0; x < list.length; x++)
list[x] = 0;
}
public void start()
{
int[] nums = {1, 2, 3, 4, 5};
int value = 6;
changeIt(nums, value);
for (int k = 0; k < nums.length; k++)
System.out.print(nums[k] + " ");
System.out.print(value);
}

(A) 0 0 0 0 0 0
(B) 0 0 0 0 0 6
(C) 123456
(D) 123450
(E) changeIt will throw an exception.
答案:C,
这道题考察的是 method 并不能真正改变实参变量的值。就是实际参数进入 changeIt 进行了运算,但是在 changeIt 结
束后,这些实际参数的变量 value name 的值并没有真的发生改变。
但是正常来说,数组作为实际参数的情况下在调用结束后值也是会变的,但是这道题因为用了 new 所以没有改变。
在start里面调用changeIt(nums, value, name)的时候他们会把他们的值分别赋值 nums{1,2,3,4,5} =>
arr,value 6=> val, 然后在 changeIt 里面本来 arr 的初始值是{1,2,3,4,5}
但是因为它第一句就是 arr = new int[5]; 所以 arr 又新建了新的数组,在内存里重新申请了 5 个int 的空间,指向了新
的数组,arr 的地址和 nums 的地址不再相同,不再指向相同的数组的起始位置,所以 arr 后面的任何数组的操作对 nums
中的值都没有产生影响
4.一维数组算法,遍历时找最大值最小值,reverse 整个数组,判断连续序列长度等,具体算法见 FRQ
葵花宝典,下面列举几道经典例题:
例:26. The code segment below is intended to print the length of the shortest string in the array
wordArray. Assume that wordArray contains at least one element.
int shortest = /* missing value */;
for (String word : wordArray)
{
if (word.length() < shortest)
{
shortest = word.length();
}
}
System.out.println(shortest);

Which of the following should be used as the initial value assigned to shortest so that the code segment
works as intended?
(A) Integer.MAX_VALUE
(B) Integer.MIN_VALUE
(C) 0
(D) word.length()
(E) wordArray.length
答案:A 寻找最小值,所以要保证数组里的值一定能小于标准值,才能把数组里的值赋值给存储最小值的变量
27.Consider the following instance variable and incomplete method. The method is intended to return a string
from the array words that would be last alphabetically.
private String[] words; public String findLastWord()
{
/* missing implementation */
}
Assume that words has been initialized with one or more strings containing only lowercase
letters. Which of the following code segments can be used to replace /* missing
implementation */ so that findLastWord will work as intended?

int maxIndex = 0;
for (int k = 0; k < words.length; k++)
{
if (words[k].compareTo(maxIndex) > 0)
(A) {
maxIndex = k;
}
}
return words[maxIndex];

int maxIndex = 0;
for (int k = 1; k <= words.length; k++)
{
if (words[k].compareTo(words[maxIndex]) > 0)
(B) {
maxIndex = k;
}
}
return words[maxIndex];

int maxIndex = 0;
for (int k = 1; k < words.length; k++)
{
if (words[k].compareTo(words[maxIndex]) > 0)
(C) {
maxIndex = k;
}
}
return maxIndex;

String maxWord = words[0];


for (int k = 1; k < words.length; k++)
{
if (words[k].compareTo(maxWord) > 0)
(D) {
maxWord = k;
}
}
return maxWord;
String maxWord = words[0];
for (int k = 1; k < words.length; k++)
{
if (words[k].compareTo(maxWord) > 0)
(E) {
maxWord = words[k];
}
}
return maxWord;

答案:E 寻找最大值的常见算法

28.Consider the following method.

Which of the following describes what the method arrayMethod() does to the array nums?
(A) The array nums is unchanged.
(B) The first value in nums is copied to every location in the array.
(C) The last value in nums is copied to every location in the array.
(D) The method generates an ArrayIndexOutOfBoundsException.
(E) The contents of the array nums are reversed.

答案:E j 从 0,数组开头开始,k 从 length-1 结尾开始,交换开头和结尾的值,j++,k--直到 j==k,所以 jk 会在中间


index 位置相遇,循环结束,交换前一半和后一半的值。所以选 E
29. Consider the following instance variable nums and method findLongest with line numbers added for reference.
Method findLongest is intended to find the longest consecutive block of the value target occurring in the array
nums; however, findLongest does not work as intended.
For example, if the array nums contains the values [7, 10, 10, 15, 15, 15, 15, 10,10, 10, 15, 10, 10], the call
findLongest (10) should return 3, the length of the longest consecutive block of 10s.
The method findLongest does not work as intended. Which of the following best describes the value returned by a
call to findLongest ?
(A) It is the length of the shortest consecutive block of the value target in nums.
(B) It is the length of the array nums.
(C) It is the number of occurrences of the value target in nums.
(D) It is the length of the first consecutive block of the value target in nums.
(E) It is the length of the last consecutive block of the value target in nums.

答案 C 因为 lenCount 没有归 0,所以会一直递增,只要有 nums 数组中有与 target 相同的值,lenCount 就会


递增
30. Which of the following changes should be made so that method findLongest will work as intended?

答案 E 应该只要走 else 即数组中的值不等于


target,lenCount 就归 0
五、MathRandom()(MCQ/FRQ 必考)

Math*Random()*n + 1 creates int value [1,n]


七 String MCQ 常考点
1. String 的拼接,String 变量用“+”加号拼接。可拼接 string 变量和 int double boolean 变量等。需要注意的是,
在出现 string 变量前,int 变量+int 变量正常计算,在出现 string 变量后,int 变量才转换为 string 变量拼接。
例:String str1 = "0";
String str2 = "abc"
String str += 0 + 8 + str1 + str2.subString(3) + str2.subString(2,3);
System.out.println(str);
结果是 “80c”,注意前面 0+8 还没开始和 String 变量拼接,所以正常运算 0+8 结果为 8,str1 为“0”,拼
在 8 后面,str2.subString(3)由于 str2 长度是 3,最大的 index 值是 2,所以是空,str2.subString(2,3)是 str2 的最
后一个字符”c”
String str1 = "It is ";
boolean guess = true;
String str2 = " that APCS is really simple, so rock on 5!";
String ret = str1 + guess + str2;
System.out.println(ret);
结果是 “It is true that APCS is really simple, so rock on 5!”
2. String 的函数
a. str.indexOf(subStr)返回 subStr 在 str 中的起始位置,str 中无 subStr 则返回-1
b. str.subString(index) 从 index 到结尾截取 str
c. str.subString(index1,index2)从 index1 到 index2-1 截取 str
d. str1 == str2, 比较 str1 和 str2 的地址是否相同,只要出现 new,地址必不同!
e. str1.equals(str2) 比较 str1 和 str2 的内容是否相同
例 String str1 = “Who is Thomas’s real husband? Jimmy or Ares?”
String str2 = str1; //str1 == str2 true, str1.equals(str2) true

String str3= new String(“Actually Thomas is the husband”);


String str4 =new String(“Actually Thomas is the husband”);
//str3 == str4 false,str3.equals(str4) true
f. str1.compareTo(str2)
a. str1 和 str2 首字母不相同时,只需比较 str1 的首字母 ASCII 码是否大于 str2,即”H” > “Dan”
ASCII 码顺序:大小写相同的情况下:字母顺序 后面的字母 > 前面的字母即(Z > A, z > a)
所有的小写字母 > 所有的大写字母 > 所有的数字
b. str1 和 str2 首字母相同时,依次向后比较对应第二位第三位上的字母,当有某一位 ACSII 不同时即产生结果,
例:“Thomas”< “ Thumas2”
c. str1 或 str2 完全包含另外一个时,长度较大的那个是大的。例“ThomasJunior”>”Thomas”
3. String 涉及结尾的几种特殊情况:
因为 String 变量其实在结尾会有一位非显式的结束符,所以 String 的实际内存占位是 string.length()+1 个字符,
因为 index 从 0 开始,所以涉及到 index 到达 string.length()时不会越界。但是超过 string.length()还是会越界!
比如 str.subString(str.length()) ==>空
str.subString(i,i)==>空
str.subString( str.length()-1,str.length())==>str 的最后一个字符,FRQ 如果用 substring(i,i+1)时一定要注意
i+1 的最大值是 length(),否则无法遍历到最后一个字符。
4. String 和 object 都是对象类型,注意当 string 或者 object 的值是 null 的时候,无法调用任何函数包括.equals()!
例:31. Consider the following class definitions.
public class Person
{
private String name;

public String getName()


{ return name; }
}

public class Book


{
private String
private String
private Person
Which of the following can replace /* missing condition */ so that the printDetails method
CANNOT cause a run-time error?
I. !borrower.equals(null)
II. borrower != null
III. borrower.getName() != null
A I only
B II only
C III only
D I and II
E II and III
答案:B, 题目中已明确说了 borrow 是 null,所以 null 不能调用任何函数,equals 和 getName()
32. Consider the following method.
public static int what(String str, String check)
{
int num = -1;
int len = check.length();
for (int k = 0; k + len <= str.length(); k++)
{
String a = str.substring(k, k + len);
if (a.equals(check))
{
num = k;
}
}
return num;
}
Assume that check occurs at least once in str. Which of the following best describes the value returned by the what
method?
(A) The number of times the string check occurs in str
(B) The index of the first occurrence of check inside str
(C) The index of the last occurrence of check inside str
(D) The number of substrings in str with the same length as check
(E) The number of substrings in str that do not match check
答案:C. int len = check.length();
for (int k = 0; k + len <= str.length(); k++)
{
String a = str.substring(k, k + len);
if (a.equals(check))
len 是 string check 的长度,for 循环 k 以 1 递增,所以每次 k 指向的位置向后移一位,
String a = str.substring(k, k + len); a 是 str 每次按照 check 的长度截取下来的子字符串,然后跟 check 比较,所以这
个循环 k 从 0 位置开始截取 check 长度字符串和 check 比较,k 后移一位,继续截取 check 长度字符串和 check 比
较,然后再后移,直到 k 移到 str.length-len 这个位置,因为这个位置再加上 len 就是 str 的结尾。每次如果截取的
字符串和 check 相等就存下来 index k,所以存的就是最后和 check 相等的字符串的位置值。
Consider the following method.
public static String[] strArrMethod(String[] arr)
{
String[] result = new String[arr.length];
for (int j = 0; j < arr.length; j++)
{
String sm = arr[j];
for (int k = j + 1; k < arr.length; k++)
{
if (arr[k].length() < sm.length())
{
sm = arr[k]; // Line 12
}
}
result[j] = sm;
}
return result;
}
33. Consider the following code segment.

String[] testOne = {"first", "day", "of", "spring"};


String[] resultOne = strArrMethod(testOne);

What are the contents of resultOne when the code segment has been executed?
(A) {"day", "first", "of", "spring"}
(B) {"of", "day", "first", "spring"}
(C) {"of", "day", "of", "spring"}
(D) {"of", "of", "of", "spring"}
(E) {"spring", "first", "day", "of"}
34. Consider the following code segment.

String[] testTwo = {"last", "day", "of", "the", "school", "year"}; String[]


resultTwo = strArrMethod(testTwo);

How many times is the line labeled // Line 12 in the strArrMethod executed as a result of executing the
code segment?
(A) 4 times
(B) 5 times
(C) 6 times
(D) 15 times
(E) 30 times
答案 33 D 34 A
String[] result = new String[arr.length];
for (int j = 0; j < arr.length; j++)
{
String sm = arr[j]; //每次把 j 位置的字符串赋值给 sm
for (int k = j + 1; k < arr.length; k++) //遍历 j 位置后面的所有字符串
{
if(arr[k].length() < sm.length()) //如果 j 后面的字符串长度小于 j 位置字符串的长度
{
sm = arr[k]; // Line 12 //j 后面字符串长度小于 sm 的长度就更新 sm,所以每发现一个
长度更短的字符串就会调用这行代码
}
} //for 循环结束
result[j] = sm; //循环结束后,将 j 位置后面最短的字符串替换 j 位置的字符串
}
return result;
第二问 A
String[] testTwo = {"last", "day", "of", "the", "school", "year"};
String[] resultTwo = strArrMethod(testTwo);
对于"last"来说,一开始 sm = "last","day"比"last"短,所以走 line12,sm 变成"day",然后"of"比"day"短,走 line12,
sm 又变成"of",之后的"the", "school", "year"都比"of"长,所以不更新不走 line12,对于 last 来说 line12 走两次
然后 sm 变成"day","of"比"day"短,所以走 line12,sm 又变成"of",之后的"the", "school", "year"都比"of"长,所以
不更新不走 line12,对于"day",line12 走 1 次
然后 sm 变成"of",之后的"the", "school", "year"都比"of"长,所以不更新不走 line12,对于"of",line12 走 0 次
然后 sm 变成"the",之后的 "school", "year"都比"the"长,所以不更新不走 line12,对于"the",line12 走 0 次
然后 sm 变成"school",之后的"year"比"school"短,走 line12 更新 1 次,所以对于"school",line12 走 1 次
最后 line12 一共走 4 次

九、二维数组
1. 二维数组主要一定要清楚循环的是行还是列
for(int i = 0; i < arr2D.length; i++) 循环的是行!!!
for(int j = 0; j < arr2D[0].length;j++) 循环的是列!!!

2.row-major 和 col-major
row-major 一行一行循环,所以外层循环是行,内层循环是列
for(int i = 0; i < arr2D.length; i++) {
for(int j = 0; j < arr2D[0].length;j++)

Col-major 一列一列循环,所以外层循环是列,内层循环是行。
for(int i = 0; i < arr2D[0].length; i++) {
for(int j = 0; j < arr2D.length;j++)

3. 对角线位置的值(行==列)
对角线上面的值 (行>列)
对角线下面的值 (行<列)
二维数组选择题主要是需要细心就没问题!
例:
35. Consider the following code segment.

int [] [] anArray = new int [10] [8];

for (int j = 0; j < 8; j++)


{
for (int k = 0; k < 10; k++)
{
anArray [j] [k] = 5;
}
}

The code segment causes an ArrayIndexOutOfBoundsException to be thrown. How many elements in


anArray will be set to 5 before the exception is thrown?
(A)
(B)
(C)
(D)
(E)
答案:B 此题 new int[10][8]所以行数是 10,列数是 8,在 for 循环中 anArray[j][k]所以 j 代表行,k 代表
列,j 从 0-7 循环没问题,k 从 0-9 循环越界,列数不足,第一次循环时 j =0,k 从 0 循环到列数 8 产生
越界,所以 set 8 个值是开始报错

36. Consider the following code segment.

String [] [] letters = {{"A", "B", "C", "D"},


{"E", "F", "G", "H"},
{"I", "J", "K", "L"}};
for (int col = 1; col < letters [0].length; col++)
{
for (int row = 1; row < letters.length; row++)
{
System.out.print (letters [row] [col] + " ");
}
System.out.println ();
}
What is printed as a result of executing this code segment?

答案:E 内层循环是 row 向下,且要注意 col 和 row 都是从 1 开始,所以第 0 行第 0 列都没有包含

37.Consider the following method, count, which is intended to traverse all the elements in the two-dimensional
(2D) String array things and return the total number of elements that contain at least one "a".

public static int count (String [] [] things)


{
int count = 0;
for (int r = 0; r < things.length; r++)
{
for (int c = 0; c < things [r].length - 1; c++)
{
if (things [r] [c].indexOf ("a") >= 0)
{
count++;
}
}
}
return count;
}

For example, if things contains {{"salad", "soup"}, {"water", "coffee"}}, then


count (things) should return 2.

The method does not always work as intended. For which of the following two-dimensional array input values does
count NOT work as intended?
(A) {{"lemon"}, {"lime"}}
(B) {{"tall", "short"}, {"up", "down"}}
(C) {{"rabbit", "bird"}, {"cat", "dog"}, {"gecko", "turtle"}}
(D) {{"scarf", "gloves", "hat"}, {"shoes", "shirt", "pants"}}
(E) {{"math", "english", "physics"}, {"golf", "baseball", "soccer"}}
答案是 D,注意上面的双重 for 循环时 c < things [r].length - 1 循环的是列,且没有循环最后一列,所以当
最后一列出现字母 a 的时候代码是不符合题意的。
十、递归(必会,大概考三题)
递归最重要 1 要有终止条件,终止条件一定是在递归语句前面,否则终止不了
38. Consider the following instance variable and methods. You may assume that data has been initialized with length > 0.
The methods are intended to return the index of an array element equal to target, or - 1 ifno such element exists.

For which of the following test cases will the call seqSearchRec(5) always result in an error?

I. data contains only one element.

II. data does not contain the value 5.

III. data contains the value 5 multiple times.


(A) I only
(B) II only
(C) III only
(D) I and II only
(E) I, II, and III
答案:B 此题 seqSearchRecHelper 会递归调用 seqSearchRecHelper, seqSearchRecHelper( int target, int
last)中调用 seqSearchRecHelper( target,last-1),如果 data[last] == target 就函数终止,如果没有 last 继
续-1 继续调用 seqSearchRecHelper( int target, int last),所以如果 target 值一直没有出现就会一直走 else
调用 seqSearchRecHelper( target,last-1),无法终止,直到数组走到 index 0 甚至-1 runtime 越界报错,
但是只要数组中包含 target 值就可以立刻返回,停止。
39.Which of the following should be used to replace // Line 1 in seqSearchRecHelper so that seqSearchRec will work
as intended?

(A)

(B)

(C)

(D)

(E)

答案:B,此题是给这个递归函数添加一个终止条件。因为 last 是一直往前走的,所以是 last==0 比较过


数组第一个值会后还没有==target 才返回-1, 所以 last =0 还没有==target,last 下一个值就是-1
40.The following question refer to the following information.
Consider the following data field and method. Method maxHelper is intended to return the largest value among the first
numVals values in an array; however, maxHelper does not work as intended.
private int [] nums;
// precondition : 0 < numVals <= nums .length
private int maxHelper (int numVals)
{
Line 1: int max = maxHelper (numVals - 1);
Line 2: if (max > nums [numVals - 1])
return max;
else
return nums [numVals - 1];

}
Which of the following corrects the method maxHelper so that it works as intended?

Insert the following statement before Line 1.


if (numVals == 0)
(A)
return numVals;

Insert the following statement before Line 1.


(B) if (numVals == 1)
return nums[0];
Insert the following statement between Line 1 and Line 2.
(C) if (numVals == 0)
return numVals;
Insert the following statement between Line 1 and Line 2.
(D) if (numVals == 1)
return nums[0];
Insert the following statement between Line 1 and Line 2.
(E) if (numVals < 2)
return numVals;
答案:B 首先终止条件一定要放在递归前面,所以 AB 中选,最后是和第一个位置作为比较值 所以是
num[0]
41.Consider the following method, which is intended to return the largest value in the portion of the int array
data that begins at the index start and goes to the end of the array.

/** Precondition: 0 <= start < data.length */


public int maximum (int [] data, int start)
{
if (start == data.length – 1)
{
return data [start];
}
/* missing statement */
if (val > data [start])
{
return val;
}
else
{

return data [start];


}
Which of the following can be used as a replacement for /* missing statement */ so that the maximum
method works as intended?
(A) int val = maximum (data, start);
(B) int val = maximum (data, start - 1);
(C) int val = maximum (data, start + 1);
(D) int val = maximum (data [start - 1], start);
(E) int val = maximum (data [start + 1], start);

答案:C
start 到数组最后一个元素时终止,所以 start 值应该在调用过程中递增
1.Consider the following method.
public static int mystery(int n)
{
if (n <= 0)
{
return 0;
}
else
{
return n + mystery(n – 2);
}
}
What value is returned as a result of the call mystery(9) ?
(A) 0
(B) 9
(C) 16
(D) 24
(E) 25
答案:E
答案 E:

2.Consider the following method.

// precondition: x >= 0
public void mystery(int x)
{
if ((x / 10) != 0)
{
mystery(x / 10);
}
System.out.print(x % 10);
}

Which of the following is printed as a result of the call mystery(123456) ?


(A) 16
(B) 56
(C) 123456
(D) 654321
(E) Many digits are printed due to infinite recursion.
答案 C

3.Consider the following method.

Which of the following is printed as a result of the call mystery(1234)?

(A) 1234
(B) 4321
(C) 12344321
(D) 43211234
(E) Many digits are printed due to infinite recursion.
答案 D
4.Consider the following recursive method.

public static String recur (int val)


{
String dig = "" + (val % 3);
if (val / 3 > 0)
return dig + recur (val / 3);
return dig;
}
What is printed as a result of executing the following statement?

System.out.println(recur(32));

(A )20
(B )102
(C )210
(D )1020
(E )2101

5.Consider the following static method.

private static void recur (int n)


{
if (n != 0)
{
recur (n - 2);
System.out.print (n + " ");
}
}

What numbers will be printed as a result of the call recur(7) ?


(A) -1 1 3 5 7
(B) 1357

(C) 7531
(D) Many numbers will be printed because of infinite recursion.
(E) No numbers will be printed because of infinite recursion

答案:E
6.Consider the following two methods, which are intended to return the same values when they are called with the
same positive integer parameter n.

public static int mystery1 (int n)


{
if (n > 1)
{
return 5 + mystery1 (n-1);
}
else
{
return 1;
}
}
public static int mystery2 (int n)
{
int total = 0;
int x = 1;
while (x < n)
{
total += 5;
x++;
}
return total;
}

Which, if any, of the following changes to mystery2 is required so that the two methods work as intended?
(A) The variable total should be initialized to 1.
(B) The variable x should be initialized to 0.
(C) The condition in the while loop header should be x < n - 1.
(D) The condition in the while loop header should be x <= n.
(E) No change is required; the methods, as currently written, return the same values when they are called with
安安
the same positive integer parameter n.
答案:(A)m(1)return 1 相当于 m2 的 total 初始值所以 total 应该为 1
7.Consider the following method.
public String goAgain (String str, int index)
{
if (index >= str.length ())
return str;
return str + goAgain (str.substring (index), index + 1);
}
What is printed as a result of executing the following statement?
System.out.println (goAgain ("today",1);
(A) today
(B) todayto
(C) todayoday
(D) todayodayay
(E) Todayodaydayayy

答案:D
8. Consider the following method.
public static void strChange (String str)
{
if (str.length () > 0)
{
strChange (str.substring (1));
System.out.print (str.substring (0, 1));
}
}
Which of the following best describes the behavior of the method?
(A) It prints the first character of str.
(B) It prints the last character of str.
(C) It prints the characters of str in the order they appear.
(D) It prints the characters of str in reverseorder.
(E) It prints nothing due to infinite recursion.

答案 D

19.The following question refer to the following information.


Consider the following data field and method. Method maxHelper is intended to return the largest value among the first
numVals values in an array; however, maxHelper does not work as intended.
private int [] nums;
// precondition : 0 < numVals <= nums .length
private int maxHelper (int numVals)
{
Line 1: int max = maxHelper (numVals - 1);
Line 2: if (max > nums [numVals - 1])

return max;

else
return nums [numVals - 1];
}
Which of the following best describe the condition under which MaxHelper doesn’t work?
(A) When numVals is 1
(B) When numVals is even
(C) When the elements of nums are in nonincreasing order
(D) When the elements of nums are in nondecreasing order
(E) Method maxHelper never works as intended.
答案: E 因为没有终止条件,不知道 numVals-1 会到什么时候终止,所以永远都不对。
Unit_8 ArrayList Summary
ArrayList is a dynamic array which can resize itself any time, and very flexible of insertion
and delete operations.
A. ArrayList elements:
ArrayList can only store object type elements , so int or double or boolean cannot be
elements of arrayList

ArrayList elements includes

Special Case:
- ArrayList repensents any type of elements
ArrayList listName = new ArrayList<>();
- ArrayList repensents more than one type of elements
ArrayList listName = new ArrayList<>();

1. Consider the following statement, which is intended to create an ArrayList named values that can be
used to store Integer elements.
/* missing code */ = new ArrayList<>();
Which of the following can be used to replace /* missing code */ so that the statement compiles without
error?
I. ArrayList values
II. ArrayList<int> values
III. ArrayList<Integer> values
(A) I only
(B) II only
(C) III only
(D) I and III only
(E) II and III only

2. Consider the following statement, which is intended to create an ArrayList named years that can be
used to store elements both of type Integer and of type String.
/* missing code */ = new ArrayList();
Which of the following can be used to replace /* missing code */ so that the statement compiles without
error?
(A) ArrayList years
(B) ArrayList years()
(C) ArrayList years[]
(D) ArrayList<Integer> years
(E) ArrayList<String> years
B. ArrayList operations
- Create ArrayList
ArrayList<Type> list = new ArrayList<Type>(); Note :List is empty without any elements
ArrayList<String> strList = new ArrayList<String>();
ArrayList<Integer> intList = new ArrayList<Integer>();
ArrayList<Double> douList = new ArrayList<Double>();
In AP exam, normally the type is another self-defined class
Example:
public class Cat{
private int size;
private String color;
public Cat() //constructor method1
{
size = 1;
color = “white”;
}
public Cat(int size, String color) //constructor method2
{
this.size = size;
this.color = color;
}
public class PetStore{
private ArrayList<Cat> list;
public PetStore() /PetStor constructor,initialize instance variable ArrayList<Cat> list
{
ArrayList<Cat> list = new ArrayList<Cat>();//list contains Cat type objects
for(int i = 0; i < list.size(); i++)
list.add(new Cat());
//Cat() method is Cat class constructor, new Cat() create a new Cat object
}
public PetStore(int[] sizes, String[] colors){//也可以调用 catClass 另一个 constructor
ArrayList<Cat> list = new ArrayList<Cat>(); //list contains Cat type objects
for(int i = 0; i < list.size(); i++)
list.add(new Cat(size[i], colors[i]));
//Cat(int size, String color) is another Cat class constructor, new Cat(size[i],colors[i]) create
a new Cat object
}
}
- add(Elements)
arrayListName.add(object); /add at the end of the arrayList
add( index, Elements)
arrayListName.add(i,object); /add at pos i, previous elements( i to end) automatically
shift right
- E set(index, Elements)
arrayListName.set(index, newObject);
Type E = arrayListName.set(index, newObject);
Note: - set operation replace object at pos index with newObject
- set operation has return type value object, the object be replaced, but use or not
use the returned object is both ok.
3. Consider the following code segment.
ArrayList<String> numbers = new ArrayList<String>();
numbers.add("one");
numbers.add("two");
numbers.add(0, "three");
numbers.set(2, "four");
numbers.add("five");
numbers.remove(1);
Which of the following represents the contents of numbers after the code segment has been
executed?
(A) ["one", "four", "five"]
(B) ["three", "two", "five"]
(C) ["three", "four", "two"]
(D) ["three", "four", "five"]
(E) ["one", "two", "three", "four", "five"] (D)

-E get(index)
arrayListName.get(index,); //Obtain an object at pos index in arrayList

Normal FRQ operations


- ArrayList stores Class Object
for( int i = 0; i < list.size() ; i++){
list.get(i).methodInTypeClass();
}
- ArrayList stores String objects
for( int i = 0; i < list.size() ; i++){
list.get(i).equals(name);
list.get(i).compareTo(names[i]);
list.get(i).compareTo(list.get(i+1); //i < list.size()-1
}
4. Consider the following method that is intended to modify its parameter nameList by replacing all
occurrences of name with newValue.
public void replace(ArrayList<String> nameList, String name, String
newValue)
{
for (int j = 0; j < nameList.size(); j++)
{
if ( /* expression */ )
{
nameList.set(j, newValue);
}
}
}
Which of the following can be used to replace /* expression */ so that replace will work as intended?
(A) nameList.get(j).equals(name)
(B) nameList.get(j) == name
(C) nameList.remove(j)
(D) nameList[j] == name
(E) nameList[j].equals(name) (A)
-E remove(index)
arrayListName.remove(index);
Type obj = arrayListName.remove(index);
 Remove FRQ important notes:
1. Remove will always have skip problem!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
for( int i = 0; i < list.size(); i++){
if(...){
list.remove(i);
}
} //skip,always wrong!!!!!!!!
Correct Remove code without skip: Must write code like this in FRQ problems!!!!
Code1:
for(int i = list.size()-1; i>0 ; i--){ //traverse from end to beginning
if(...){
list.remove(i);
}
}

Code2:
int i = 0;
while( i <list.size()){
if(...)
list.remove(i); //when remove, do not increase i;
else
i++; //increase i only when no remove operation happens
}
2. Remove has return type, return the removed object, which is always
used in FRQ
For Example
Create a new list to store removed objects:
ArrayList<Type> rList = new ArrayList<Type>();
for(int i = oldList.size(); i > 0; i--){ //remove FRQ always traverse backwards!!!!
if(...){
rList.add(oldList.remove(i)); //directly add removed item in new list
}
}
 Remove MCQ questions, skip is still the most important point
3. The removeElement method is intended to remove all instances of target from the ArrayList
object data passed as a parameter. The method does not work as intended for all inputs.
public void removeElement(ArrayList<Integer> data, int target)
{
for (int j = 0; j < data.size(); j++)
{
if (data.get(j).equals(target))
{
data.remove(j);
}
}
}
Assume that the ArrayList object scores and the int variable low_score have been properly
declared and initialized. In which of the following cases will the method call removeElement(scores,
low_score) fail to produce the intended result?
(A) When scores is [0, 2, 0, 2, 0, 6] and low_score is 0
(B) When scores is [2, 4, 0, 5, 7, 0] and low_score is 0
(C) When scores is [3, 4, 5, 7, 7, 2] and low_score is 1
(D) When scores is [8, 8, 4, 3, 3, 6] and low_score is 3
(E) When scores is [9, 9, 5, 9, 7, 7] and low_score is 5
解析:8 8 4 3 3 6 假如找 8 代表 i 循环到的元素,所以 8 被跳过去了
Index 01234
此题条件是 if (data.get(j).equals(target))
不管是什么条件,比如 if (data.get(j)%2==0) 原题 intend remove all even number,如果有两个偶数连着,
第二个偶数还是会被 skip
所以只要有两个都符合条件的数连着,第一个被 remove 了之后,第二个就会被 skip!!!!

题型 2 removedumps 删除重复的数字,intend to keep ONLY one copy of each value.


2. The following question refer to the following information.
Consider the following data field and method. The method removeDups is intended to remove all
adjacent duplicate numbers from myData, but does not work as intended.
private ArrayList myData;
public void removeDups ()
{
int k = 1;
while (k < myData.size())
{
if (myData.get(k).equals(myData.get(k - 1)))
{
myData.remove(k);
}
k++;
}
}
For example,if myData has the values 334448777, after calling removeDups,myData should have the values 3
4 8 7.
Assume that myData has the following values. 2 7 5 5 5 5 6 6 3 3 3
Which of the following represents myData after the incorrect removeDups is executed?
(A) 2 7 5 6 3
(B) 2 7 5 6 3 3
(C) 2 7 5 5 6 3 3
(D) 2 7 5 5 5 6 3 3
(E) 2 7 5 5 5 5 6 6 3

解析: 2 7 5 5 5 5 6 6 3 3 3 (C)
代表 i 循环到的元素, 只有发生删除的时候, 才会跳!

3. Consider the following method, which is intended to return a list containing the elements of the parameter
myList with all even elements removed.
public static ArrayList<Integer> removeEvens(ArrayList<Integer> myList)
{
for (int i = 0; i < myList.size(); i++)
{
if (myList.get(i) % 2 == 0)
{
myList.remove(i);
}
}
return myList;
}
Which of the following best explains why the code segment does not work as intended?
(A) The code segment causes an IndexOutOfBoundsException for all lists because of an incorrect
Boolean expression in the for loop
. (B) The code segment causes an IndexOutOfBoundsException for lists with at least one even element
because the indexes of all subsequent elements change by one when a list element is removed
(C) The code segment returns a list with fewer elements than intended because it fails to consider the last
element of myList.
(D) The code segment removes the wrong elements of myList because the condition in the if statement to
test whether an element is even is incorrect.
(E) The code segment skips some elements of myList because the indexes of all subsequent elements
change by one when a list element is removed
Answer (E)

4.Consider the following method.


/** Removes all occurrences of nameToRemove from nameList.
*@param nameList a list of names
*@param nameToRemove a name to be removed from nameList
*/
public void removeName(List<String> nameList, String nameToRemove)
{ /* missing implementation */
}
Which of the following can be used to replace /* missing implementation */ so that removeName will work as
intended?
I.for(String name : nameList)
{
if (name.equals(nameToRemove))
name.remove();
}
II.for (int k = 0; k < nameList.size(); k++)
{
if (nameList.get(k).equals(nameToRemove))
nameList.remove(k);
}
III.for (int k = nameList.size() - 1; k >= 0; k--)
{
if (nameList.get(k).equals(nameToRemove))
nameList.remove(k);
}
(A) I only
(B) II only
(C) III only
(D) II and III only
(E) I, II, and III
Answer (C)
5. The following question refer to the following information.
Consider the following data field and method. The method removeDupsisintended to remove all adjacent
duplicate numbers from myData, but does not work asintended.
private ArrayList myData;
public void removeDups ()
{
int k = 1;
while (k < myData.size())
{
if (myData.get(k).equals(myData.get(k - 1)))
{
myData.remove(k);
}
k++;
}
}
For example,if myData hasthevalues 334448777, after calling removeDups,myData should have the
values 3 4 8 7.
Which of the following best describes how to fix the error so that removeDups works as intended?
(A) k should be initialized to 0 at the beginning of the method.
(B) The while condition should be (k < myData.size() - 1).
(C) The if test should be (myData.get(k).equals(myData.get(k + 1))).
(D) The body of the if statement should be: myData.remove(k - 1);
(E) There should be an else before the statement k++;
Answer E
UNIT10 Search&Sort Summary
A. BinarySearch
二分法查找:
Precondition:序列或数组已经是有序数组,注意数组中元素可能有重复值,一般为递增数组{1,5,7,7,8,8,9}
PostCondition:二分法查找返回 target 在序列中的位置 index
二分法查找算法描述:
- 因为序列本身是有序比如递增的,所以每次判断 target 落在前半区域还是后半区域即可直接缩小一半的查找范围,一
直分半查找,直到 target 值正好在某个 mid 值的位置,返回 mid 值
- 第一次循环时,起始位置为 0,终止位置为 length-1,中间位为 mid = (start+end)/2
- 每次循环时,如果 target < arr[mid],说明 target 落在左半部分,从 mid 位置到最后的所有值一定都大于 target 可以扔掉
了,所以 end 左移至 mid-1
- 每次循环时,如果 target > arr[mid],说明 target 落在右半部分,从 start 位置到 mid 位置的所有值一定都小于 target 可以
扔掉了,所以 start 右移至 mid+1
- 每次更改 start end 值后重新计算 mid
二分法执行次数:
log2 数组长度 例:log28 = 3
二分法代码示例:
数组非递归版本:
public int binarySearch(int[] sortedArray, int target){
int min = 0, max = sortedArray.length – 1;
while (min <= max) {
int mid = (min + max) / 2;
if (sortedArray[mid] < target)
min = mid + 1;
else if (sortedArray[mid] > target)
max = mid - 1;
else if (sortedArray[mid] == target)
return mid;
}
return -1;
}
数组递归代码:
public static int bSearch(int[] arr, int left, int right, int x) {
if (right >= left){
int mid = (left + right) / 2;
if (arr[mid] == x){
return mid;
}
else if (arr[mid] > x){
return bSearch(arr, left, mid - 1, x);//change right to mid-1
}
else{
return bSearch(arr, mid + 1, right, x);//change left to mid+1
}}//end right>=left
return -1;
}

AP Computer Science A Page 1 of 19


常考题型:
1 给定一个数组和 target 值,判断 binarySearch 返回值
Consider the following method, which implements a recursive binary search.

/** Returns an index in myList where target appears,


* if target appears in myList between the elements at indices
* low and high, inclusive; otherwise returns -1.
* Precondition: myList is sorted in ascending order.
* low >= 0, high < myList.size (), myList.size () > 0
*/
public static int binarySearch (ArrayList<Integer> myList,
int low, int high, int target)
{
int mid = (high + low) / 2; if
(target < myList.get (mid))
{
return binarySearch (myList, low, mid - 1, target);
}
else if (target > myList.get (mid))
{
return binarySearch (myList, mid + 1, high, target);
}
else if (myList.get (mid).equals (target))
{
return mid;
}
return -1;
}

Assume that inputList is an ArrayList of Integer objects that contains the following values.

[0, 10, 30, 40, 50, 70, 70, 70, 70]

What value will be returned by the call binarySearch (inputList, 0, 8, 70) ?


(A) -1
(B) 5
(C) 6
(D) 7
(E) 8

Loop1: start = 0,end = 8 mid = 4, inputList.get(mid) = 50, 70 > 50 所以落在右半部分


Loop2:start = mid+1 变 5,end = 8,mid 变 6,inputList.get(mid) =70 正好等于 target,
答案为 6

AP Computer Science A Page 1 of 19


2.给定一个数组和 target 值,判断 binarySearch 执行次数

2. Consider the following method.

// precondition : arr contains no duplicates;


//the elements in arr are in sorted order;
// 0 ≤ low ≤ arr.length; low - 1 ≤ high < arr.length
public static int mystery (int low, int high, int num)
{
int mid = (low + high) / 2; if
(low > high)
{
return low;
}
else if (arr [mid] < num)
{
return mystery ( mid + 1, high, num);
}
else if (arr [mid] > num)
{
return mystery ( low, mid - 1, num);
}
else // arr{mid] == num
{
return mid;
}
}

How many calls to mystery (including the initial call) are made as a result of the call mystery(arr, 0, arr.length - 1,
14) if arr is the following array?

0 1 2 3 4 5 6 7

arr 11 13 25 26 29 30 31 32

(A) 1
(B) 2
(C) 4
(D) 7
(E) 8

注意本题 14 并不在数组中,所以要注意循环终止条件,if(low > high)return low;


Loop1 start 0 end 7 mid 3,mid 值 26, 14 < 26
Loop2 start 0 end2 mid 1, mid 值 13, 14 > 13
Loop3 start 2, end 2, mid2 不符合中止条件继续判断,mid 值 25, 14 < 25
Loop4 start2 end 1, start > end 符合终止条件,返回 start2

AP Computer Science A Page 1 of 19


B. SelectionSort 选择排序
选择排序算法概述,数组 8,5,4,3,2,6,7 为例
选择排序每次循环 1 确定一个要被交换的数 8
2 在包含要被交换的数,直到最后,寻找最小值 在 8,5,4,3,2,6,7 中寻找最小值 2
3 最小值与要被交换的数进行位置交换 2,5,4,3,8,6,7
4 要被交换的位置向后移一位
第二轮循环 1 确定一个要被交换的数 5
2 在包含要被交换的数,直到最后,寻找最小值 在 5,4,3,8,6,7 中找最小值 3
3 最小值与要被交换的数进行位置交换 2,3,4,5,8,6,7
4 要被交换的位置向后移一位

选择排序思想:第一次循环找出最小值放在第一个位置,第二次循环找出第二小的放在第二个位置,第三次循环找
出第三小放在第三个位置,所以每次循环后,前面的序列逐渐变为递增的有序序列直到整个数组遍历结束。
所以每次查找时,序列分为三个部分:
2,3,4,5,4,6,7 2,3 是已经排好序的部分,4 是待交换的值,5,8,6,7 待排序序列
选择排序代码:
public static void selectionSort(int arr[]){
for (int i = 0; i < arr.length - 1; i++){
int min_idx = i; //i 即为每次要被交换的位置,i 赋值给 min_idx 保证被交换的值也能在 寻找
最小值过程中包含在内

//j 的起始位置为未排序的初始位置所以是 i+1 循环遍历包含 min_idx 在内和 min_idx 后面的值,寻找最小



for (int j = i+1; j < arr.length; j++){
if (arr[j] < arr[min_idx])
min_idx = j;
}
//找到的最小值和 i 位置的值交换
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
public static void selectSort(int[] arr){
for (int pass = arr.length - 1; pass >= 1; pass--){ //倒序循环
int index = 0;
int large = arr[index];
for (int k = 0; k <= pass; k++){ //倒序循环,所以每次把最大/最小值放在最后,需要排序的范围从 0
到未排序位置,所以是 k = 0; k <= pass;
if (arr[k] > arr[index]){
large = arr[k];
index = k;
}}
arr[index] = arr[pass];
arr[pass] = large;
}}

选择排序快速判断排序结果的方法
1 根据代码是否有交换值代码判断是否是选择排序
2 判断循环中找的是最大值还是最小值
3 看最初始最外层循环起始位置,如果是 0 就是把最大值或者最小值放在第一个位置,如果是 length-1 就是把最小值
放在最后位置,来判断选择排序最终生成的是递增还是递减序列
Page 18 of 19 AP Computer Science A
选择排序考察题型:选择题,
考查知识点:
1 寻找最小值的语句执行次数,交换代码执行次数等,所以必须非常清楚选择排序的过程
2 寻找最小值或者最大值时一定要记得包含将被交换的那个值,判断哪个代码正确
3 给定待排序数组或者序列,判断排序结果,递增还是递减
例题:
Consider the following correct implementation of the selection sort algorithm.
public static void selectionSort (int [] elements){
for (int j = 0; j < elements.length - 1; j++)
{
int minIndex = j;
for (int k = j + 1; k < elements.length; k++)
{
if (elements [k] < elements [minIndex])
{
minIndex = k;
}
}
if (j != minIndex)
{
int temp = elements [j];
elements [j] = elements[minIndex];
elements [minIndex] = temp; // Line 19
}
}
}
The following declaration and method call appear in a method in the same class as selectionSort.
int[] arr = {9, 8, 7, 6, 5};
selectionSort (arr);
How many times is the statement elements [minIndex] = temp; in line 19 of the method executed
as a result of the call to selectionSort ?
(A) 1
(B) 2
(C) 3
(D) 4
(E) 5
9 8 7 6 5 考查交换次数 第一次循环 9 和 5 交换 序列变为 5 8 7 6 9
第二次循环 从 8 开始找最小值 6,6 和 8 交换,序列变为 5 6 7 8 9 序列已经有序结束,所以交换代码执行了 2 次
7. Consider the following correct implementation of the selection sort algorithm.
public static void selectionSort(int arr[]){
for (int i = 0; i < arr.length - 1; i++){
int min_idx = i;
for (int j = i+1; j < arr.length; j++){
if (arr[j] < arr[min_idx])
min_idx = j;
}
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
Page 19 of 19 AP Computer Science A
The following declaration and method call appear in the same class as selectionSort.

int [] vals = {5, 10, 2, 1, 12};


selectionSort (vals);

How many times is the statement minIndex = k; in line 11 of the method executed as a result of the call
to selectionSort ?
(A) 0
(B) 1
(C) 2
(D) 3
(E) 4
解析:minIndex = k;语句是寻找最小值过程中,每次找到更小的值就赋值位置 k 给 minIndex
5 10 2 1 12 第一次循环时 被交换值为 5, 2 < 5 minIndex 变为 2 的位置,1 小于 2minIndex 变为 1 的位置执行了
2 次,序列变为 1 10 2 5 12
第二次循环时,被交换值为 10, 2 < 10, minIndex 变为 2 的位置,后面没有比 2 小的,不再交换,执行 1 次,
序列变为 1 2 10 5 12
第三次循环时,被交换值为 10, 5<10 minIndex 变为 5 的位置,后面没有比 5 更小的,执行 1 次,序列变为 1
2 5 10 12 已有序,结束。所以执行了 4 次

C. InsertionSort 插入排序
插入排序算法概述,数组 8,5,4,3,2,6,7 为例
插入排序从数组第二个数开始,第二个数即为要插入的数,如果比前一个数小,则前一个数后移,第二数放在第
一个位置,如果大于等于前一个数,不变
接下来第三个数,第三个数即为要插入的数,如果比前面数大,前面数后移,直至前面的数小于当前要
被插入的数为止,被插入的数找到了自己的位置,插入该位置
接下来递增要插入的数,直到最后一个。

数组 8,5,4,3,6,7 为例
Loop1 5 为要插入的数 5 < 8 ,8 后移,5 插入第一个位置,数组变为 5,8,4,3,2,6,7
Loop2 4 为要插入的数,4 < 8, 8 后移一位,4 < 5,5 后移一位,4 插入第一位,序列变为 4,5,8,3,2,6,7
Loop3 3 为要插入的数,3 < 8, 8 后移一位,3 < 5,5 后移一位,3<4, 4 后移一位, 3 插入第一位,序列变为
3,4,5,8,6,7
Loop4 6 为要插入的数,6 < 8, 8 后移一位,6 > 5,6 插入,序列变为 3,4,5,6,8,7
Loop4 7 为要插入的数,7 < 8, 8 后移一位,7 > 6,7 插入,序列变为 3,4,5,6,7,8

D. MergeSort 排序
排序算法,将序列不断分为两半分两半直到每半只有一个元素为止
然后 merge 一个和一个排好序 merge 成两个 两个和两个排好序 merge 成四个。。。一直到最后
以 8,5,4,3,2,6,7,9 为例
1 拆成 8 5 4 3 和 2 6 7 9
2 再拆成 8 5 和 4 3 和 2 6 和 7 9
3 再拆成 8 和 5 4 和 3 2 和 6 7 和 9
4 merge: 8 和 5 merge 成 5 8 4 和 3 merge 成 3 4 2 和 6merge 成 2 6 7 和 9merge 成 7 9
5 merge: 5 8 和 3 4 merge 成 3 4 5 8, 2 6 和 7 9 merge 成 2 6 7 9
6 merge: 3 4 5 8 和 2 6 7 9 merge 成 2 3 4 5 6 7 8 9

Page 20 of 19 AP Computer Science A


Page 21 of 19 AP Computer Science A
Test Booklet

Inheritance & Method overload Summary


一、总述:

1. public class subClass extends superClass

extends左边为子类,右边为父类

子类继承表现两种行为:继承和Extend

继承(inheritance):

a. 子类继承父类的: private instance variables

all public method

b. 子类没有继承父类的: constructor函数

Extend:

a. 子类可以声明自己新的instance variable(父类中没有的)

b. 子类可以生明自己新的public method(父类中没有的)

c. 子类可以改写(override)父类中继承的public method,即父类

子类函数名相同,参数列表相同,函数内容不同(表现不同的行为)

d. 子类必须重写自己的constructor函数

- 并且通常显式(explicitly)通过super关键字调用父类的构造函

数,无参构造函数或有参构造函数,有时可能会出现父类无无参构造函

数或者子类没有显式通过super调用父类构造函数的情况。见下方详解。

二、Inheritance常考题型:

A. 父类new 子类,子类new子类等

a. 父类 obj = new 父类构造函数();

obj 只能调用父类中的所有函数,且表现父类的行为

b. 父类 obj = new 子类构造函数();

obj 只能调用父类中的所有函数,不能调用子类中自己的新函数,
Test Booklet

且如果obj调用了被子类改写的父类函数,则表现子类的行为。

如果obj调用的父类函数没有被子类改写,则仍表现父类的行为,即相当

于子类继承来的相同的行为。

因为java编译时,代码从左往右读,会认为obj是个父类的obj,所以obj

只 能 调 用 父 类 中 的 函 数 。 但 是 运 行 时 发 现 obj 实 际 是 调 用 的 子 类 的

constructor函数构造的对象,所以运行时会表现子类的行为。

c. 子类 obj = new 子类构造函数()

obj 可以调用父类和子类中的所有函数,因为父类中的函数全部都被子

类继承,可调用;子类自己新创建的函数,子类也可以调用。且全部表现子

类的行为。

d. 子类 obj = new 父类构造函数()

错误!!!越级!!!

例题在知识点总结后。

B. 子类通过super关键字表现父类的行为

子类函数中表现一部分父类的行为,即在子类的非构造函数中通过super.(点)

父类函数名调用父类的函数,然后继续执行子类函数的语句,接着表现子类的行

为。
public class Artifact
{
private String title;
private int year;
public Artifact(String t, int y)
{
title = t;
year = y;
}
public void printInfo()
{
System.out.print(title + " (" + year + ")");
}
}
Test Booklet

public class Artwork extends Artifact


{
private String artist;
public Artwork(String t, int y, String a)
{
super(t, y);
artist = a;
}
public void printInfo()
{
super.printInfo();
System.out.println( “by artist” + artist);
}
}
子类的printInfo会先调用父类的printInfo函数 print title和year注意是print
所以没有换行,执行父类的printInfo后再执行子类的println打印artist信息,因为
父类是print无换行,所以artist部分会紧接着year打印。之后再换行。
C.子类父类Constructor函数

子类调用父类的构造函数分为以下四种情况

1)最通常的情况父类中既包含无参构造函数,又包含有参构造函数
public class superClassName{
type instanceVar1;
type instanceVar2;
public superClassName()
{
instanceVar1 = default value;
instanceVar2 = default value;
}
public superClassName(type var1, type var2)
{
instanceVar1 = var1;
instanceVar2 = var2;
}
}

子类显式(explictily)调用父类的无参或者有参构造函数,初始化父类的

instance variables
Test Booklet

public class subClassName extends superClassName


{
type newInstanceVar3;

//子类的无参构造函数可以显式调用父类的无参或有参构造函数
public subClassName()
{
super();
newInstanceVar3 = default value;
}
或者:
public subClassName()
{
super( type var1,type var2);
newInstanceVar3 = default value;
}
//子类的有参构造函数也可以显式调用父类的无参或有参构造函数
public subClassName(type var3)
{
super();
newInstanceVar3 = var3;
}
或者:
public subClassName(type var3)
{
super( type var1,type var2);
newInstanceVar3 = var3;
}
}
2)父类中既包含无参构造函数,又包含有参构造函数,但是子类没有显

式的调用父类的构造函数,即子类构造函数中没有出现super关键字,这时子类

会隐式的(implicitly)调用父类的无参构造函数,注意是调用无参的!隐式指的

是没有明确的写出super但是程序的运行过程中仍然会去调用会根据super的无
Test Booklet

参构造函数的代码完成superClass的instance variable的初始化赋值。

- 父类仍既包含无参构造函数和有参构造函数
public class superClassName{
type instanceVar1;
type instanceVar2;
public superClassName() //Line4
{
instanceVar1 = default value; //Line5
instanceVar2 = default value; // Line6
}
public superClassName(type var1, type var2){
instanceVar1 = var1;
instanceVar2 = var2;
}
}
- 子类的构造函数没有明确写出super关键字
public class subClassName extends superClassName{
type newInstanceVar3;
public subClassName()
{
newInstanceVar3 = default value;
}
public subClassName(type var3)
{
newInstanceVar3 = var3;
}
}
子类的无参构造函数无super关键字,但子类仍会implicitly调用父类的无
参构造函数
即上面的line3,line4,line5将父类的instanceVar1和instanceVar2初
始化为默认值
public subClassName(){
newInstanceVar3 = default value;
}
Test Booklet

子类的有参构造函数无super关键字,但子类仍会implicitly调用父类的
无参构造函数
即上面的line3,line4,line5将父类的instanceVar1和instanceVar2
初始化为默认值
public subClassName(type var3)
{
newInstanceVar3 = var3;
}
3)父类中并没有明确写出无参的构造函数,但是明确写了有参构造函数,

且子类显式的调用父类的无参构造函数。注意,此时java不会给父类提供默认的

无参构造函数。 报错!!!此知识点CB未出过题目

代码示例如下:

注意:父类中并没有明确写出无参构造函数,但是有明确写了有参构造

函数
public class Bike {
private int numOfWheels = 2;

public Bike(int numOfWheels)


{
this.numOfWheels = numOfWheels;
}
public int getNumOfWheels()
{
return numOfWheels;
}
}
子类明确地(explictily)调用了父类的无参构造函数
public class EBike extends Bike
{
private int numOfWatts;
public EBike(int watts)
{
super(); //CompileTime Error!!!!!!
numOfWatts = watts;
}
public int getNumOfWatts()
{ return numOfWatts; }
}
Test Booklet

4)父类中并没有明确写出无参的构造函数,也没有有参构造函数,即父类没

有任何构造函数的情况下!Java会给父类提供默认的无参构造函数!

此时,子类 explicitly 通过super() 调用父类无参构造函数 √


子类 explicitly 通过super(type var1,type var2)调用父类有参

构造函数 × (因为父类并没有有参的构造函数)

子类不写任何super语句,只初始化自己的new instance variable √


(子类会implicitly调用父类的无参构造函数,即java提供的默认构造函数)将

所有父类的instance variable都初始化为默认值
public class Bike {
private int numOfWheels = 2;

/* no constructor method*/
public int getNumOfWheels(){
return numOfWheels;
}
}
父类没有任何构造函数,java才会提供一个默认的无参构造函数。
public class EBike extends Bike{
private int numOfWatts;
public EBike(int watts,int numWheels)
{
super(); // OK!!!
Super(numWheels); //Error!!!SuperClass无有参constructor
numOfWatts = watts;
}
public EBike(int watts)
{
numOfWatts = watts;// OK!Implicitly call java提供的父类
无参构造函数! }
public int getNumOfWatts()
Test Booklet

{ return numOfWatts; }
}
三、Method Overload(函数重载)

Method Overload即函数名相同,但是函数的参数个数不同,或者函数参

数个数相同,但是不同类型参数顺序不同。

Method Overload分为合法的重载和不合法的重载(即会报错!)

不合法的重载,通常是两个函数参数个数相同,但是相同类型的参数顺序不

同导致在实际调用函数时,并不能通过实际参数区分调用的到底是哪个函数。

比如:

public Book(Sting bookTitle,String author,int numPages);

public Book(String author,String bookTitle,int numPages);

以上两个函数再实际调用时,比如

Book book1 = new Book(“GoneWithWind”, “Margaret Mitchell”,544);

Book book2 = new Book(“Les Misérables”,“Victor Hugo”,783);

前面两个参数都是String变量,并不能根据变量明确知道哪个该赋值给

bookTitle,哪个赋值给author,所以无法区分book1和book2实际调用的是哪

个bookConstructor,所以是无效的method overload;

有效的Method overload比如:

public Book(Sting bookTitle,String author,int numPages);

public Book(String author,int numPages, String bookTitle);

此 时 的 两 个 Book constructor 在 放 入 实 际 参 数 时 , 可 以 区 分 author 和

bookTitle分别是第一个第二个变量或者第一个第三个变量,所以是有效的

method Overload
Test Booklet

四.重点例题解析:

A. 父类new子类等:
public class Animal
{
public void eat()

{ /* implementation not shown */ }

// constructors and other methods not shown


}
public class Tiger extends Animal
{
public void roar()
{ /* implementation not shown */ }
// constructors and other methods not shown

Assume that the following declaration appears in a client class.


Animal a = new Tiger();
Which of the following statements would compile without error?

I. a.eat();

II.a.roar();

III. ((Tiger) a).roar();

(A) I only

(B) II only

(C) III only

(D) I and III only

(E) I, II, and III

解析:选D Animal是父类,Tiger是子类,父类Animal a = new 子类构造函数

Tiger(),所以a只能调用父类Animal的函数eat(), 不能调roar(),所以II不对, III

对a进行了强制转换为子类就可以调用子类的函数roar()了
Test Booklet

public class C1
{
public C1()
{ /* implementation not shown */ }
public void m1()
{ System.out.print("A"); }
public void m2()
{ System.out.print("B"); }
}

public class C2 extends C1


{
public C2()
{ /* implementation not shown */ }
public void m2()
{ System.out.print("C"); }
}

}
The following code segment appears in a class other than C1 or C2.

C1 obj1 = new C2();


obj1.m1();
obj1.m2();

The code segment is intended to produce the output AB. Which of the following best
explains why the code segment does not produce the intended output?
(A) A compile-time error occurs because obj1 is declared as type C1 but instantiated as type C2.
(B) A runtime error occurs because method m1 does not appear in C2.
(C) Method m1 is not executed because it does not appear in C2.
(D) Method m2 is executed from the subclass instead of the superclass because obj1 is
instantiated as a C2 object.
(E) Method m2 is executed twice (once in the subclass and once in the superclass) because it
appears in both classes.

解析:选D C1是父类,C2是子类,父类C1 obj1 = new 子类构造函数C2(),所以

obj1只能调用父类C1函数m1和m2, 调用没有问题。

此题说调用m1()和m2()后要打印”AB”但是打印的结果不对。

调用m1()时,只有父类有m1(),子类继承父类的m1(),所以表现父类的行为打印

A,调用m2()时,子类父类都有m2(),所以表现子类的m2()行为,打印的是C所

以选D, 子类的m2被执行,因为obj1被初始化为子类的object
Test Booklet

B. 子类中用super调用父类函数,表现一部分父类行为:

1.Consider the following classes.


public class Ticket
{
private double price;
public Ticket(double p)
{
price = p;
}
public double getPrice()
{
return price;
}
public String toString()
{
return "Price is " + getPrice();
}
}

public class DiscountTicket extends Ticket


{
public DiscountTicket(double p)
{
super(p);
}
public double getPrice()
{
return super.getPrice() / 2.0;
}
}

The following code segment appears in a class other than Ticket or DiscountTicket.

Ticket t = new DiscountTicket(10.0); System.out.println(t);

What output, if any, is produced when the code segment is executed?

(A) 5.0
(B) 10.0
(C) Price is 5.0
(D) Price is 10.0
(E) There is no output because the code does not compile.

解析:选C,此题父类是Ticket t = new子类构造函数DicountTicket(10.0)
Test Booklet

System.out.println(t)默认调用的是toString函数

此题首先Ticket t = new子类构造函数DicountTicket(10.0)时调用子类的构造

函数
public DiscountTicket(double p)
{
super(p);
}
子类的构造函数调用了父类的有参构造函数,并将参数值10.0传给父类
public Ticket(double p)
{
price = p;
}
所以父类的price值为10.0

之后System.out.println(t)默认调用的是toString函数
public String toString()
{
return "Price is " + getPrice();
}

toString()在父类中定义且没有被子类改写,所以表现父类的行为
return "Price is " + getPrice();

toString()函数又调用了getPrice()函数,getPrice()在父类子类中都有,且t是

new子类构造函数新建的object,所以表现子类的行为所以会调用子类的

getPrice()函数即
public double getPrice()
{
return super.getPrice() / 2.0;
}
在子类的getPrice()函数中又通过super.调用了父类的getPrice()函数,并将父类

的getPrice()函数结果/2.0后返回,所以先看父类的getPrice()函数:
public double getPrice()
{
return price;
}
Test Booklet

直接返回price的值是一开始调子类构造函数初始化的10.0

10.0/2.0后是5.0所以这就是return super.getPrice() / 2.0;子类getPrice()函数的

返回结果

接着toString(){ return "Price is " + getPrice();}

所以返回值为 “Price is 5.0”选C

C. 父类子类constructor MCQ例题

1. Consider the following class definitions.

Which of the following can be used to replace /* missing implementation */


so that the Textbook constructor compiles without error?
Test Booklet

解析: D. super(the_author, the_title) 调用父类的constructor 函数初始


化父类的所有instance variable
subject = the_subject //初始化subClass’s own instance variable
A. Wrong! subClass constructor cannot directly access superClass’s

instance variables

B. Wrong! super(the_subject) is wrong, superClass does not have a one

parameter constructor method

C. Wrong! super(parameter) should always be first line!

D. Correct

E. Wrong! super cannot initialize both superClass&subClass instance

variables

2. Consider the following class declarations.


public class A
{
private int x;
public A()
{
x = 0;
}
public A(int y)
{
x = y;
}
// There may be instance variables, constructors, and methods that are
not shown.
}
public class B extends A
{
private int y;
public B()
{
/* missing code */
}
// There may be instance variables, constructors, and methods that are
not shown.
}
Which of the following can be used to replace /* missing code */ so that the
Test Booklet

statement

B temp = new B();


will construct an object of type B and initialize both x and y with 0 ?
I. y = 0;
II. super (0);
y = 0;
III. x = 0;
y = 0;

(A) I only

(B) II only

(C) I and II only

(D) II and III only

(E) I, II, and III


解析: 答案是C
父类是Class A 子类是class B 子类B = new 子类();
本题考察子类的构造函数
I 仅有一行 y =0;
没有明确调用super(),但是父类有无参的构造函数,
所以会隐式地(implicitly)调用父类的无参构造函数

public A()
{
x = 0;
}
so x is 0 then y = 0, assigns 0 to y
II super(0) ; y = 0;
显式调用父类的有参构造函数
public A(int y)
{
x = y;
}
所以x =0,Then y = 0, 最终 x = 0 y= 0
Test Booklet

III
x = 0 is wrong, x is instance variable in superClass, cannot be
directly accessed in subClass
3. Consider the following class definitions.

public class Bike

private int numWheels = 2;

// No constructor defined

public class EBike extends Bike

private int

numBatteries;

public EBike(int batteries)

numBatteries = batteries;

The following code segment appears in a method in a class other than

Bike or EBike.

EBike eB = new EBike(4);

Which of the following best describes the effect of executing the code
Test Booklet

segment?

An implicit call to the zero-parameter Bike constructor initializes the

instance variable
(A) numWheels. The instance variable numBatteries is initialized using
the value of the parameter
batteries.
An implicit call to the one-parameter Bike constructor with the
parameter passed to
(B) the EBike constructor initializes the instance variable numWheels.
The instance variable
numBatteries is initialized using the value of the parameter batteries.

Because super is not explicitly called from the EBike constructor, the
instance variable numWheels
(C) is not initialized. The instance variable numBatteries is initialized
using the value of the parameter
batteries.
(D) The code segment will not execute because the Bike class is a

superclass and must have a constructor.

(E) The code segment will not execute because the constructor of

the EBike class is missing a second parameter to use to

initialize the numWheels instance variable.

答案是 A 此题父类没有任何构造函数,所以java会提供一个默认的无参

构造函数,因为子类也没有明确的super关键字调用父类的构造函数,所

以会隐式地调用父类的无参构造函数,选A

You might also like