第 五 章
決定
5.1 if 敘述
if (amount <= balance)
balance = balance - amount;
if/else 敘述
if (amount <= balance)
balance = balance - amount;
else
balance = balance - OVERDRAFT_PENALTY;
Block 敘述
if (amount <= balance)
{
double newBalance = balance - amount;
balance = newBalance;
}
Syntax 5.1. if 敘述
| |
if(condition)
statement
if (condition)
statement
else
statement
|
例題:
| |
if (amount <= balance) balance = balance - amount;
if (amount <= balance) balance = balance - amount; else balance = balance - OVERDRAFT_PENALTY;
|
用途:
To execute a statement when a condition is true or false |
Syntax 5.2. Block 敘述
| |
{
statement
statement
. . .
}
|
例題:
| |
{
double newBalance = balance - amount;
balance = newBalance;
}
|
用途:
To group several statements together to form a single statement |
敘述型式
- 簡單敘述
balance = balance - amount;
- 複雜敘述
if (balance >= amount) balance = balance - amount;
Also while, for, etc. (see chapter 6)
- Block 敘述
{
double newBalance = balance - amount;
balance = newBalance;
}
5.2 數值的比較
關係運算子
Java
|
Math Notation
|
Description
|
>
|
>
|
Greater than
|
>=
|
≥
|
Greater than or equal
|
<
|
<
|
Less than
|
<=
|
≤
|
Less than or equal
|
==
|
=
|
Equal
|
!=
|
≠
|
Not equal
|
相等和指定
- == 測試是否相等:
if (x == 0) . . // if x equals zero
- = 指定一數值給一變數:
x = 0; // assign 0 to x
- 注意不要用錯
浮點數比較
浮點數比較
- 兩數幾乎相等, 假如
|x - y| <= ε
- ε 是一很小的數, 如 10-14
- 假如 x, y 很大或很小, 不足以判斷, 就必須用
|x - y| / max(|x|, |y|) <= ε
- 但是But if one of the numbers is zero, don't divide by max(|x
|, |y|)
字串比較
- 不要用 == 比較字串!
if (input == "Y") // WRONG!!!
- 用 equals 方法:
if (input.equals("Y"))
- == 測試身份, equals 測試內容是否相同
- 大小寫不拘時 (如 "Y" or "y") 用 equalsIgnoreCase()
if (input.equalsIgnoreCase("Y"))
依字典的次序比較(Lexicographic Comparison)
Java 所用的次序,數字在前,接著大寫字母,再接著小寫字母。
- s.compareTo(t) < 0 表示:
在字典中 s 是在 t 之前
- "car" 在 "cargo" 之前
"cargo" 在 "cathode" 之前
- 所有大寫字母都在小寫字母之前, 如:
"Hello" 在 "car" 之前
依字典的次序比較
物件比較
- == 測試身份, equals 測試內容是否相同
- Rectangle cerealBox = new
Rectangle(5, 10, 20, 30);
Rectangle oatmealBox = new
Rectangle(5, 10, 20, 30);
Rectangle r = cerealBox;
- cerealBox != oatmealBox,
but
cerealBox.equals(oatmealBox)
- cerealBox == r
- Caveat: equals must be defined for the class (see chapter
11)
物件比較
The null Reference
- null reference refers to no object at all
- 可用於測試:
if (account == null) . . .
- 用 ==, 不是用 equals, 測試 null
- 假如用者按下取消鍵 showInputDialog 傳回 null:
String input = JOptionPane.showInputDialog("...");
if (input != null) { ... }
- null 不是空字串 ""
5.3 多重選擇(Multiple Alternatives)
- if (condition1)
statement1;
else if (condition2)
statement2;
else if (condition3)
statement3;
else
statement4;
- The first matching condition is executed.
- Order matters.
File Earthquake.java
/**
A class that describes the effects of an earthquake.
*/
public class Earthquake
{
/**
Constructs an Earthquake object.
@param magnitude the magnitude on the Richter scale
*/
public Earthquake(double magnitude)
{
richter = magnitude;
}
/**
Gets a description of the effect of the earthquake.
@return the description of the effect
*/
public String getDescription()
{
String r;
if (richter >= 8.0)
r = "Most structures fall";
else if (richter >= 7.0)
r = "Many buildings destroyed";
else if (richter >= 6.0)
r = "Many buildings considerably damaged, some collapse";
else if (richter >= 4.5)
r = "Damage to poorly constructed buildings";
else if (richter >= 3.5)
r = "Felt by many people, no destruction";
else if (richter >= 0)
r = "Generally not felt by people";
else
r = "Negative numbers are not valid";
return r;
}
private double richter;
}
File EarthquakeTest.java
import javax.swing.JOptionPane;
/**
A class to test the Earthquake class.
*/
public class EarthquakeTest
{
public static void main(String[] args)
{
String input = JOptionPane.showInputDialog(
"Enter a magnitude on the Richter scale:");
double magnitude = Double.parseDouble(input);
Earthquake quake = new Earthquake(magnitude);
System.out.println(quake.getDescription());
System.exit(0);
}
}
多重選擇
- 測試的先後次序會影�g結果Order matters:
if (richter >= 0) // always passes
r = "Generally not felt by people";
else if (richter >= 3.5) // not tested
r = "Felt by many people, no destruction";
. . .
- 不要漏了 else
if (richter >= 8.0)
r = "Most structures fall";
if (richter >= 7.0) // omitted else--ERROR
r = "Many buildings destroyed
多層分支(Nested Branches)
所得稅申報
假如婚姻狀況是單身
所得總額超過
|
但未超過
|
稅額為
|
總額超過
|
$0
|
$21,450
|
15%
|
$0
|
$21,450
|
$51,900
|
$3,217.50 + 28%
|
$21,450
|
$51,900
|
|
$11,743.50 + 31%
|
$51,900
|
假如婚姻狀況是已婚
所得總額超過
|
但未超過
|
稅額為
|
總額超過
|
$0
|
$35,800
|
15%
|
$0
|
$35,800
|
$86,500
|
$5,370.00 + 28%
|
$35,800
|
$86,500
|
|
$19,566.00 + 31%
|
$86,500
|
所得稅申報流程圖
File TaxReturn.java
/**
A tax return of a taxpayer in 1992.
*/
class TaxReturn
{
/**
Constructs a TaxReturn object for a given income and
marital status.
@param anIncome the taxpayer income
@param aStatus either SINGLE or MARRIED
*/
public TaxReturn(double anIncome, int aStatus)
{
income = anIncome;
status = aStatus;
}
public double getTax()
{
double tax = 0;
if (status == SINGLE)
{
if (income <= SINGLE_CUTOFF1)
tax = RATE1 * income;
else if (income <= SINGLE_CUTOFF2)
tax = SINGLE_BASE2
+ RATE2 * (income - SINGLE_CUTOFF1);
else
tax = SINGLE_BASE3
+ RATE3 * (income - SINGLE_CUTOFF2);
}
else
{
if (income <= MARRIED_CUTOFF1)
tax = RATE1 * income;
else if (income <= MARRIED_CUTOFF2)
tax = MARRIED_BASE2
+ RATE2 * (income - MARRIED_CUTOFF1);
else
tax = MARRIED_BASE3
+ RATE3 * (income - MARRIED_CUTOFF2);
}
return tax;
}
public static final int SINGLE = 1;
public static final int MARRIED = 2;
private static final double RATE1 = 0.15;
private static final double RATE2 = 0.28;
private static final double RATE3 = 0.31;
private static final double SINGLE_CUTOFF1 = 21450;
private static final double SINGLE_CUTOFF2 = 51900;
private static final double SINGLE_BASE2 = 3217.50;
private static final double SINGLE_BASE3 = 11743.50;
private static final double MARRIED_CUTOFF1 = 35800;
private static final double MARRIED_CUTOFF2 = 86500;
private static final double MARRIED_BASE2 = 5370;
private static final double MARRIED_BASE3 = 19566;
private double income;
private int status;
}
File TaxReturnTest.java
/**
A tax return of a taxpayer in 1992.
*/
class TaxReturn
{
/**
Constructs a TaxReturn object for a given income and
marital status.
@param anIncome the taxpayer income
@param aStatus either SINGLE or MARRIED
*/
public TaxReturn(double anIncome, int aStatus)
{
income = anIncome;
status = aStatus;
}
public double getTax()
{
double tax = 0;
if (status == SINGLE)
{
if (income <= SINGLE_CUTOFF1)
tax = RATE1 * income;
else if (income <= SINGLE_CUTOFF2)
tax = SINGLE_BASE2
+ RATE2 * (income - SINGLE_CUTOFF1);
else
tax = SINGLE_BASE3
+ RATE3 * (income - SINGLE_CUTOFF2);
}
else
{
if (income <= MARRIED_CUTOFF1)
tax = RATE1 * income;
else if (income <= MARRIED_CUTOFF2)
tax = MARRIED_BASE2
+ RATE2 * (income - MARRIED_CUTOFF1);
else
tax = MARRIED_BASE3
+ RATE3 * (income - MARRIED_CUTOFF2);
}
return tax;
}
public static final int SINGLE = 1;
public static final int MARRIED = 2;
private static final double RATE1 = 0.15;
private static final double RATE2 = 0.28;
private static final double RATE3 = 0.31;
private static final double SINGLE_CUTOFF1 = 21450;
private static final double SINGLE_CUTOFF2 = 51900;
private static final double SINGLE_BASE2 = 3217.50;
private static final double SINGLE_BASE3 = 11743.50;
private static final double MARRIED_CUTOFF1 = 35800;
private static final double MARRIED_CUTOFF2 = 86500;
private static final double MARRIED_BASE2 = 5370;
private static final double MARRIED_BASE3 = 19566;
private double income;
private int status;
}
使用布林(boolean)式
boolean 型式
- George Boole (1815-1864): 邏輯研究的先驅者
- 式子值 amount < 1000 是 true 或
false.
- boolean 型式: true 或
false
斷定性方法(Predicate Method)
- 回值的型式為 boolean
- 例子:
public boolean isOverdrawn()
{
return balance < 0;
}
- 用於測試條件中
if (harrysChecking.isOverdrawn()) ...
- Character 類別中, 有用的斷定性方法有:
isDigit
isLetter
isUpperCase
isLowerCase
- if (Character.isUpperCase(ch)) ...
布林運算子
- && and
- || or
- ! not
- if (0 < amount && amount < 1000) ...
- if (input.equals("S") || input.equals("M")) ...
&& 和 || 運算子
真實表(Truth Tables)
A
|
B
|
A && B
|
true
|
true
|
true
|
true
|
false
|
false
|
false
|
Any
|
false
|
A
|
B
|
A || B
|
true
|
Any
|
true
|
false
|
true
|
true
|
false
|
false
|
false
|
A
|
! A
|
true
|
false
|
false
|
true
|
De Morgan's 定律
- 否定一複雜條件容易引起混淆:
if (!(0 < amount && amount < 1000))
- De Morgan's 定律說明
!(A && B) 和 !A || !B 相同
!(A || B) 和 !A && !B 相同
- 注意 ! 移入括弧內 && 和 || 對調
- (!(0 < amount && amount < 1000)) 即
!(0 < amount) || !(amount < 1000) , 即
0 >= amount || amount >= 1000
- 注意 < 的相反是 >=
布林變數
- private boolean married;
- 設定的是真實值:
married = input.equals("M");
- 在條件中使用:
if (married) ... else ...
if (!married) ...
- 不要測試布林變數是否等(或不等)於真實值之一, 如:
if (married == true) // DON'T
if (married == false) // DON'T
if (married != false) // NO!!!