学习Java核心技术 卷Ⅰ(三)

目录

控制流程

块作用域

条件语句

形式一 

形式二 

形式三

循环 

循环一

循环二 

确定性循环 

多重选择:switch 语句

中断控制流程的语句

大数


控制流程

块作用域

        块(block)(即复合语句)由若干条 Java 语句组成,并用一对大括号括起来。块确定了变量的作用域。一个块可以嵌套在另一个块中,但是不能在嵌套的两个块中声明同名变量。

public static void main(String[] args)
{
    int n;
    . . .
    // 嵌套在 main 方法中的块:
    {
        int k;
        int n; // 不可以定义与上级块中同名的变量
        . . .
    }
}

条件语句

形式一 

if (condition) statement

这里的条件必须用小括号括起来 

if (yourSales >= target)
{
    performance = "Satisfactory";
    bonus = 100;
}

if流程图: 

形式二 

if (condition) statement1 else statement2  

if (yourSales >= target)
{
    performance = "Satisfactory";
    bonus = 100 + 0.01 * (yourSales - target);
}
else
{
    performance = "Unsatisfactory";
    bonus = 0;
}

// unsatisfactory    adj.不令人满意的,不符合要求的

if...else... 流程图 :

形式三

反复使用 if...else if...

if (yourSales >= 2 * target)
{
    performance = "Excellent";
    bonus = 1000;
}
else if (yourSales >= 1.5 * target)
{
    performance = "Fine";
    bonus = 500;
}
else if (yourSales >= target)
{
    performance = "Satisfactory";
    bonus = 100;
}
else
{
    System.out.println("You're fired");
}


/**
target    n.目标
performance    n.表现
bonus     n.奖金
excellent    adj.极好的,卓越的
fine    adj.好的
satisfactory    adj.令人满意的
fire    v.解雇
*/

反复使用 if...else if... 流程图 :

循环 

循环一

while (condition) statement

while 循环会在条件为 true 时执行一个语句(也可以是一个块语句)。

如果开始循环条件就为 false,那么 while 循环一次也不执行

// 计算需要多长时间才能够存下一定数量的退休金,假设每年存入相同金额,而且利率是固定的
while (balance < goal)
{
    balance += payment;
    double interest = balance * interestRate / 100;
    balance += interest;
    years++;
}

/**
payment    n.付款
balance    n.余额
interest    n.利息
*/

while 语句的流程图 :

wile 计算退休金完整代码:

import java.util.*;

/**
 * This program demonstrates a <code>while</code> loop.
 *
 * @author Cay Horstmann
 * @version 1.20 2004-02-10
 */
public class Retirement {
    public static void main(String[] args) {
        // 读取输入
        Scanner in = new Scanner(System.in);

        System.out.print("How much money do you need to retire? ");
        double goal = in.nextDouble();

        System.out.print("How much money will you contribute every year? ");
        double payment = in.nextDouble();

        System.out.print("Interest rate in %: ");
        double interestRate = in.nextDouble();

        double balance = 0;
        int years = 0;

        // update account balance while goal isn't reached
        while (balance < goal) {
            // add this year's payment and interest
            balance += payment;
            double interest = balance * interestRate / 100;
            balance += interest;
            years++;
        }

        System.out.println("You can retire in " + years + " years.");
    }
}

循环二 

do statement while (condition)

        这种循环先执行语句(通常是一个语句块),然后再检查循环条件。如果条件为 true,就重复执行语句,然后再此检测循环条件,以此类推。 

do
{
    balance += payment;
    double interest = balance * interestRate / 100;
    balance += interest;
    years++;
    // print current balance
    . . .
    // ask if ready to retire and get input
    . . .
}
while (input.equals("N"));

do/while 语句的流程图: 

do/while 语句的流程图

do/while 计算退休金完整代码 :

import java.util.*;

/**
 * This program demonstrates a <code>do/while</code> loop.
 *
 * @author Cay Horstmann
 * @version 1.20 2004-02-10
 */
public class Retirement2 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        System.out.print("How much money will you contribute every year? ");
        double payment = in.nextDouble();

        System.out.print("Interest rate in %: ");
        double interestRate = in.nextDouble();

        double balance = 0;
        int year = 0;

        String input;

        // update account balance while user isn't ready to retire
        do {
            // add this year's payment and interest
            balance += payment;
            double interest = balance * interestRate / 100;
            balance += interest;

            year++;

            // print current balance
            System.out.printf("After year %d, your balance is %,.2f%n", year,
                    balance);

            // ask if ready to retire and get input
            System.out.print("Ready to retire? (Y/N) ");
            input = in.next();
        }
        while (input.equals("N"));
    }
}

确定性循环 

for (初始条件; 循环检测条件; 循环后更新计数器) {
    // 执行语句
}

一些规则:

        1.for 语句的 3 个部分应该对同一个计数器变量进行初始化、检测和更新。若不遵守,所写的循环可能晦涩难懂。

        2.在 for 语句的第 1 部分中声明一个变量之后,这个变量的作用域会扩展到这个 for 循环体的末尾。

        3.如果在 for 语句内部定义一个变量,这个变量就不能在循环体之外使用。因此,如果希望在 for 循环体之外使用循环计数器的最终值,就要确保在循环体之外声明这个变量。

        4.可以在不同的 for 循环中定义同名的变量 

        5.for 循环语句只是 while 循环的一种简化形式。

警告:在循环中,检测连个浮点数是否相等需要格外小心。下面的 for 循环:

        for (double x = 0; x != 10; x += 0.1) . . .

        可能永远不会结束。由于存在舍入误差,可能永远达不到精确的最终值。在这个例子中,因为0.1无法精确地用二进制表示,所以,x 将从 9.99999999999998 跳到 10.09999999999998。

for 语句的流程图:

for 循环计算抽奖概率代码 :

        一般情况下,如果从 n 个数字中抽取 k 个数字,就会有:

种可能。

import java.util.*;

/**
 * This program demonstrates a <code>for</code> loop.
 * @version 1.20 2004-02-10
 * @author Cay Horstmann
 */
public class LotteryOdds
{
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        
        System.out.print("How many numbers do you need to draw? ");
        int k = in.nextInt();
        
        System.out.print("What is the highest number you can draw? ");
        int n = in.nextInt();
        
        /*
         * compute binomial coefficient n*(n-1)*(n-2)*...*(n-k+1)/(1*2*3*...*k)
         */
        
        int lotteryOdds = 1;
        for (int i = 1; i <= k; i++)
            lotteryOdds = lotteryOdds * (n - i + 1) / i;
        
        System.out.println("Your odds are 1 in " + lotteryOdds + ". Good luck!");
    }
}

多重选择:switch 语句

Scanner in = new Scanner(System.in);
System.out.print("Select an option (1, 2, 3, 4) ");
int choice = in.nextInt();
switch (choice)
{
case 1 ->
. . .
case 2 ->
. . .
case 3 ->
. . .
case 4 ->
. . .
default ->
System.out.println("Bad input");
}

         以上代码是根据下面的流程图所创建出来的,其中

        case 标签可以是:

                1.类型为 char、byte、short 或 int 的常量表达式

                2.枚举常量

                3.字符串字面量

                4.多个字符串,用逗号分隔

switch 语句的流程图:

        switch 语句从与选项值相匹配的 case 标签开始执行,直到遇到下一个 break 语句,或者执行到 switch 语句结束。如果没有匹配的 case 标签,则执行 default 子句(如果有 default 子句)。

警告: 有可能触发多个分支。如果忘记在一个分支末尾增加 break 语句,就会接着执行下一个分支!这种情况相当危险,常常会引发错误。

        为了检测这种问题,编译代码时可以加上 -Xlint:fallthrough 选项,如下所示:

        javac -Xlint:fallthrough Test.java

        这样一来,如果某个分支最后缺少一个 break 语句,编译器就会给出一个警告。

        如果你确实想使用这种“直通式”(fallthrough)行为,可以为其外围方法加一个注解@SuppressWarnings("fallthrough")。这样就不会对这个方法生成警告了。(注解是为编译器或处理 Java 源文件或类文件的工具提供信息的一种机制。卷 Ⅱ 会深入介绍注解。)

4 种 switch 形式: 

选择:switch 表达式优于语句,无直通行为由于有直通行为

注解:完全可以在 switch 表达式的一个分支中抛出异常。例如:

        default -> throw new IllegalArgumentException("Not a valid season");  

警告:switch 表达式的关键是生成一个值(或者产生一个异常而失败)。不允许“跳出”switch表达式:

        default -> { return -1; } // ERROR

具体来讲,不能在 switch 表达式中使用 return、break 或 continue 语句。

中断控制流程的语句

        break  和  带标签的 break

        continue 和 带标签的 continue

大数

         如果基本的整数和浮点数不足以满足需求,那么可以使用 java.math 包中两个很有用的类:BigInteger 和 BigDecimal。

        BigInteger 类实现任意精度的整数运算,BigDecimal 类实现任意精度的浮点数运算

        使用静态的 valueOf 方法可以将一个普通的数转换为大数:

        BigInteger a = BigInteger.valueOf(100);

        对于更长的数,可以使用一个带字符串参数的构造器:

        BigInteger reallyBig = new BigInteger("22554462626622626266...")

         另外还有一些常量:BigInteger.ZERO、BigInteger.ONE、BigInteger.TEN、以及 Java 9 之后还增加了 BigInteger.TWO. 

警告:对于 BigDecimal 类,总是应当使用带一个字符串参数的构造器。还有一个 BigDecimal(double)构造器,不过这个构造器本质上很容易产生舍入误差,例如,new BigDecimal(0.1) 会得到以下数位: 0.1000000000000000055511151231257827021181583404541015625。
        遗憾的是,不能使用人们熟悉的算术运算符(如:+ 和 -)来组合大数,而需要使用大数类中的 add 和 multiply 方法。

       

计算抽奖概率代码:(从n个数中抽取k个数中奖概率)

import java.math.*;
import java.util.*;

/**
 * This program uses big numbers to compute the odds of winning the grand prize in a lottery.
 * @version 1.20 2004-02-10
 * @author Cay Horstmann
 */
public class BigIntegerTest {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        System.out.print("How many numbers do you need to draw? ");
        int k = in.nextInt();

        System.out.print("What is the highest number you can draw? ");
        BigInteger n = in.nextBigInteger();

        /*
         * compute binomial coefficient n*(n-1)*(n-2)*...*(n-k+1)/(1*2*3*...*k)
         */
        BigInteger lotteryOdds = BigInteger.ONE;

        for (int i = 1; i <= k; i++) 
            lotteryOdds = lotteryOdds.
                multiply(n.subtract(BigInteger.valueOf(i - 1))).
                divide(BigInteger.valueOf(i));
        
        System.out.printf("Your odds are 1 in %s. Good luck!%n", lotteryOdds);
    }
}

 

大数常见API:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值