Java核心技术卷I (11版)第三章学习(三)

Java核心技术卷I (11版)第三章学习(三)

读取输入

  1. 使用nextLine方法,是因为在输入行中有可能包含空格。
  2. 要想读取一个单词(以空白符作为分隔符),可以使用in.next()方法。
  3. 读取一个整数,调用nextInt()方法。
  4. 读取下一个浮点数,调用nextDouble()方法。
import java.util.*;

// 创建与“标准输入流”System.in关联的Scanner对象
Scanner in = new Scanner(System.in);

// 使用in的方法nextLine()读取一行输入
System.out.println("名字:");
String name = in.nextLine();
// nextLine()以回车作为结束,空格作为字符也会被读取

// 想读取一个单词(以空白符作为分隔符)
String name = in.next();

// 读取一个整数
Int age = in.nextInt();
import java.util.Scanner;

// 创建与“标准输入流” System.in关联的Scanner对象
Scanner in = new Scanner(System.in);

// 使用nextLine方法读取一行输入
System.out.println("你叫啥?");
String name = in.nextLine();
// 读取一个单词
String firstName = in.next();

// 读取一个整数
System.out.println("多大了?");
int age = in.nextInt();

// 读取一个浮点数使用in.nextDouble()
  1. Scanner类定义在Java.util包中,在文件的最前面加上代码import Java.uti.*;即可。
  2. boolean hasNext():检测输入中是否还有其他单词。
  3. boolean hasNextInt():检测输入中是否还有下一个表示整数的字符序列。
  4. boolean hasNextDouble():检测输入中是否还有下一个表示浮点数的字符序列。

由于输入可见,所以Scanner类不适用于从控制台读取密码,Java6引入了Console类来实现密码读取。

Console cons = System.console();
String username = cons.readLine("User name: ");
char[] passwd = cons.readPassword("Password: ");
  1. 使用System.console()来获取一个与当前Java虚拟机关联的控制台对象,然后使用该控制台对象的方法来读取输入。
  2. 采用Console对象来获取输入,必须每次读取一行输入,没有读取单个单词或数值的方法。
  3. public static Console console():如果可以交互,就返回一个Console对象通过控制台窗口与用户交互,否则返回null
  4. 在图形用户界面(GUI)环境中,System.console() 可能会返回 null,因为GUI通常不提供与控制台相对应的输入/输出流。
public class ConsoleExample{
	public static void main(String[] args){
		// 获取控制台对象
		Console cons = System.console();
		if (console == null){
			System.out.println("No console available.");
             return;
		}
        
        // 读取用户名
        String name = cons.readLine("Your name: ");
        
        // 读取密码(不会显示内容)
        char[] password = cons.readPassword("Password: ");
        
        // 出于安全考虑,处理完密码后清楚密码数组内容
        java.util.Arrays.fill(password, ' ');
	}
}
  1. Console对象读取的密码会存储在字符数组中保存,而不是字符串中。

格式化输出

// Java5沿用了C语言函数库的printf()方法
System.out.printf("%8.2f", x);  // 总共8哥字符,小数点后2个字符

System.out.printf("Hello, %s, Next year, you'll be %d", name, age);

// 创建格式化的字符串
String message = String.format("Hello, %s. Next year, you'll be %d", name, age);

// 打印当前的日期和时间
System.out.printf("%tc", new Date());
  1. f表示浮点数,s表示字符串,d表示十进制整数,b是布尔,c是字符。

文件输入与输出

import java.io.IOException;  // 使用try catch需要导入的包
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Scanner;

public class ScannerFileExample {  
    public static void main(String[] args) {  
        String filePath = "myfile.txt";  
          
        // 读取文件  
        try (Scanner scanner = new Scanner(Path.of(filePath), StandardCharsets.UTF_8)) {  
            while (scanner.hasNextLine()) {  // 如果存在下一行内容,则执行下述内容
                String line = scanner.nextLine();  
                // 在这里处理读取到的每一行内容
                System.out.println(line);  //打印到控制台
            }  
        } catch (IOException e1) {  
            e1.printStackTrace();  
        }
        
        try (PrintWriter writer = new PrintWriter(filePath, StandardCharsets.UTF_8)){
        	writer.println("写入内容!");
        }catch(IOException e2) {
        	e2.printStackTrace();
        }
    }
}
  1. 在创建Scanner对象时,不能写成Scanner in = new Scanner("filePath.txt");,这样会导致Scanner把字符串解释为数据,而不是文件名,所以需要使用Path.of("filePath.txt")
  2. StandardCharsets.UTF_8用于指定字符编码。
  3. 为什么要使用try-catch包围?
    • try-catch语句块石一种处理运行时错误或异常的机制。这种机制允许程序在检测到错误时执行特定的代码块(例如与该错误匹配的catch块),而不是立即崩溃或者停止。

控制流程

import java.util.*;
import java.io.*;

public class Example_3_5{
	public static void main(String[] args) {
		// 在嵌套的块中无法重复定义变量
		int n=1;
		
		{
			//int n; //报错
			int k;
		}
		
		
		// if语句
		if(2>n) {
			System.out.println("2大于n");
		}else if(2==n){
			System.out.println("2等于n");
		}else {
			System.out.println("2小于n");
		}
		
		// 循环语句
		while(n<5) {
			System.out.println(n);
			n++;
		}  // while语句中,若条件为True,则执行下述内容,条件判定先于内容运行
		
		do {
			System.out.println(n);
			n++;
		}while(n<10);  // do while语句中,先执行内容,再进行条件判定
		
		for (int i=1; i<15; i++) {
			System.out.println(n);
		}
		
		for ( ; n<20; n++) { //变量n已经定义,不需要再定义(此循环前n=10)
			System.out.println(n);
		}
		
		int choice = 2;
		switch(choice) {
			case 1:
				System.out.println("choice值为1。");
				break;
			case 2:
				System.out.println("choice值为2。");
				break;
			default:
				System.out.println("choice值超出范围。");
				break;
		}
	}
}
块作用域
  1. 块一般以大括号为界定符,例如上述代码就是由三个块嵌套起来的
  2. java在嵌套的块中不能重定义一个变量。但是在C++中,可以在嵌套的块中重新定义这个变量。
break语句
  1. break语句通常用于提前终止当前循环(如forwhiledo-while循环)。然而,当存在多层嵌套循环时,直接使用break只能跳出最内层的循环。若想跳出多层嵌套循环,需要用到带标签的break。
  2. 在下述例子中,当i * j等于9时,程序会跳出标签为outerLoop的循环,即使它位于内层循环内部。注意,标签必须放在它要标记的循环之前,并且在该循环的范围内是可见的。
outerLoop: for (int i = 0; i < 5; i++) {  
    for (int j = 0; j < 5; j++) {  
        if (i * j == 9) {  
            break outerLoop; // 当i和j的乘积等于9时,跳出外层循环  
        }  
        System.out.println("i = " + i + ", j = " + j);  
    }  
}
continue语句
  1. continue语句在编程中用于控制循环的流程。当在循环体内遇到continue语句时,程序会跳过当前循环迭代中continue之后的所有剩余语句,并立即开始下一次迭代。换句话说,continue语句用于结束当前循环迭代,而不是终止整个循环。
  2. for循环中,continue语句会导致程序流程直接跳到循环头部的更新表达式,并开始下一次迭代。在while循环中,continue语句会导致程序流程直接回到循环的条件判断部分。
#include <stdio.h>

int main() {
    for (int i = 0; i < 10; i++) {
        if (i == 5) {
            continue; // 当i等于5时,跳过本次循环的剩余部分
        }
        printf("%d ", i); // 输出除了5以外的数字
    }
    return 0;
}

// 输出结果为:0 1 2 3 4 6 7 8 9
  1. 同样地,在while循环中也可以使用continue语句。
  2. 下述代码的输出结果与上面的for循环示例相同。需要注意的是,在while循环中,通常建议在continue语句之前更新循环变量(在这个例子中是i),以确保循环能够正常进行到下一次迭代。
#include <stdio.h>

int main() {
    int i = 0;
    while (i < 10) {
        i++;
        if (i == 5) {
            continue; // 当i等于5时,跳过本次循环的剩余部分
        }
        printf("%d ", i); // 输出除了5以外的数字
    }
    return 0;
}

大数

java.math包中有两个类BigIntegerBigDecimal,可以处理包含任意长度数字序列的数值。前者实现任意精度的证书运算,后者实现任意精度的浮点数运算。

BigInteger
  1. 构造器:可以通过字符串或字节数组创建 BigInteger 实例。
BigInteger bigIntFromString = new BigInteger("12345678901234567890");
BigInteger bigIntFromByteArray = new BigInteger(byteArray);
  1. 算术操作:支持加、减、乘、除等基本算术操作。
BigInteger a = new BigInteger("1234567890");
BigInteger b = new BigInteger("9876543210");

BigInteger sum = a.add(b);
BigInteger difference = a.subtract(b);
BigInteger product = a.multiply(b);
BigInteger quotient = a.divide(b);  // 注意:可能会抛出 ArithmeticException 如果 a 不能被 b 整除
BigInteger remainder = a.mod(b);
  1. 比较:可以使用 compareTo 方法比较两个 BigInteger 的大小。
int comparisonResult = a.compareTo(b);
if (comparisonResult < 0) {
    System.out.println("a is less than b");
} else if (comparisonResult > 0) {
    System.out.println("a is greater than b");
} else {
    System.out.println("a is equal to b");
}
  1. 位移操作:可以左移或右移指定的位数。
BigInteger shiftedLeft = a.shiftLeft(3);  // 等同于 a * 2^3
BigInteger shiftedRight = a.shiftRight(2);  // 无符号右移
  1. 转换为基本类型:可以将 BigInteger 转换为基本类型,但这在数值非常大时会导致溢出。
BigInteger bigInt = new BigInteger("31623189273812783101747180471274");
long longValue = bigInt.longValue();  // 注意:如果 bigInt 太大,这里会发生溢出
  1. 位操作:支持 AND、OR、XOR 和 NOT 等位操作。
  2. 其他操作:还有很多其他有用的方法,如计算幂、计算最大公约数(GCD)、求模逆元等。
BigDecimal

java.math.BigDecimal 类提供了用于任意精度的十进制算术运算的不可变对象。与 BigInteger 类似,BigDecimal 允许你对非常大的或非常小的浮点数进行精确计算,而不会遇到浮点数运算中常见的舍入误差。

  1. 构造器:可以通过字符串、数字或 BigInteger 创建 BigDecimal 实例。
  • BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常,如:BigDecimal g= new BigDecimal(0.1F);实际的存储值为0.10000000149。
  • 优先推荐入参为String 的构造方法,或使用BigDecimalvalueOf方法,此方法内部其实执行了Double toString,而DoubletoStringdouble的实际能表达的精度对尾数进行了截断。
BigDecimal bdFromString = new BigDecimal("123.456");
BigDecimal bdFromDouble = new BigDecimal(123.456); // 不推荐,因为 double 不精确
BigDecimal bdFromBigInteger = new BigDecimal(BigInteger.valueOf(123456), 3); // 123.456,第二个参数是小数点后的位数
  1. 算术操作:支持加、减、乘、除等基本算术操作。
BigDecimal a = new BigDecimal("10.0");
BigDecimal b = new BigDecimal("3.0");

BigDecimal sum = a.add(b); // 加法
BigDecimal difference = a.subtract(b); // 减法
BigDecimal product = a.multiply(b); // 乘法
BigDecimal quotient = a.divide(b, 2, RoundingMode.HALF_UP); // 除法,指定小数位数和舍入模式
  1. 比较:可以使用 compareTo 方法比较两个 BigDecimal 的大小。
int comparisonResult = a.compareTo(b);
if (comparisonResult < 0) {
    System.out.println("a is less than b");
} else if (comparisonResult > 0) {
    System.out.println("a is greater than b");
} else {
    System.out.println("a is equal to b");
}
  1. 数值操作:可以设置小数点后的位数、进行舍入、求绝对值等。
BigDecimal rounded = a.setScale(2, RoundingMode.HALF_UP); // 设置小数点后位数并进行舍入
BigDecimal absolute = a.abs(); // 求绝对值
  1. 转换为基本类型:可以将 BigDecimal 转换为基本类型,但这在数值非常大或非常小时可能会导致溢出或丢失精度。
double doubleValue = bd.doubleValue(); // 转换为 double,可能丢失精度

BigDecimal 在金融计算、科学计算、税务计算等需要高精度小数运算的领域非常有用。在这些场景中,使用 floatdouble 类型可能会导致不可接受的误差。

笔记目录
Java核心技术卷I (11版)第二章学习
Java核心技术卷I (11版)第三章学习(一)
Java核心技术卷I (11版)第三章学习(二)
Java核心技术卷I (11版)第三章学习(三)

  • 29
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值