Java 核心技术卷I 读书笔记

Posted 吞吞吐吐大魔王

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 核心技术卷I 读书笔记相关的知识,希望对你有一定的参考价值。

2021/8/3

3.5 运算符

  1. 关键字 strictfp

    • 对于使用 strictfp 关键字标记的方法必须使用严格的浮点计算来生成可再生的结果,如

      可以把 main 函数标记为

      public static strictfp void main(String[] args)
      

      于是 main 函数中的所有指令都将使用严格的浮点计算

    • 在默认情况下,虚拟机设计者允许对中间计算结果采用扩展的精度

    • 上述两者区别仅仅在于默认情况不会产生溢出,而采用严格的计算有可能产生溢出

  2. Math 类

    1. sqrt 方法

      计算平方根,如

      double x=4;
      double y=Math.sqrt(x);
      System.out.println(y);
      

      println 方法和 sqrt 方法存在微小差异。

      1. println 方法处理 System.out 对象
      2. Math 类中的 sqrt 方法处理的不是对象,这样的方法叫作静态方法
    2. pow 方法

      在 java 中没有幂运算,需要借助 Math 类的 pow 方法,如

      double y=Math.pow(x,a);
      
    3. floorMod 方法

      floorMod 其方法实就是求余,不同于 % 符号来求余数,它还可以对负数求余(正符合“欧几里得”规则:余数总是要 ≥ 0),如

      double y=Math.floorMod(m,n);
      //求 m 除 n 的余数
      

      但是如果除数是负数,即 n 是负数,则 floorMod 会得到负数结果

    4. 常用三角函数

      Math.sin / Math.cos/ Math.tan / Math.atan/ Math.atan2

    5. 指数函数以及反函数

      Math.exp / Math.log / Math.log10

    6. 常量 Π 和 e 的近似值

      Math.PI / Math.E

    不必在数学方法名和常量前名前加 “Math”,只要在源文件顶部加上

    import static java.lang.Math.*;
    
  3. 数值类型之间的转换

    1. 直接附书中一张图片吧!图里面实心箭头表示无信息丢失的转换,虚线箭头表示可能有精度损失的转换。

      但是问题来了,我开始疑惑为什么 int 转 float 是虚线箭头,按理说 float 表示的数值范围要比 int 多呀!后来经过思考我发现,如果int类型的值在 224 以内,float 是可以精确表示的,但是当超过这个数的时候就不一定能精确表示了。如果想要搞清楚的话,大家可以先去我之前写的 剖析C语言数据在内存中的存储 这篇文章里了解浮点型在内存中的存储。

    2. 两个数值进行计算时,如果都是 int 类型一下的就都要先转换为 int 类型,其他的都要先转换为这个数中数值范围更大的那个类型。

  4. 强制类型转换

    强制类型转换有两种方法

    1. (要转换类型)+ 待转换变量名,如

      double x=9.997;
      int ly=(int)x;
      

      ly 的结果是9,这种转换通过截断小数部分将浮点值转换为整型。如果你想对浮点数进行舍入运算,就要用到下面的方法。

    2. Math.round 方法,如

      double x=9.997;
      int ly=(int)Math.round(x);
      

      ly 的结果是10,但是为什么前面还是加了(int)呢?因为 round 方法返回的结果为 long 类型,防止信息丢失的可能,需要强制转换

    注意:如果强制转换的类型的值超过了该类型的范围,则结果就会被截断为完全不同的值

  5. 关系运算符

    和 C 语言一样,&& 表示逻辑“与”,|| 表示逻辑“或”。但是要注意它们会按照“短路”方法求值,如

    exp1 && exp2
    

    只要 exp1 是假,那么第二个表达式则不进行计算。再如

    exp1 || exp2
    

    只要 exp1 是真,那么第二个表达式则不进行计算。

  6. 位运算符

    1. 和 C 语言一样,java 有 & 和 | 和 ^ 和 ~。但是位运算符与关系运算符的 && 和 ||不同的是,它们不采用“短路”方法求值,即计算结果之前两个数都要计算
    2. 应用在布尔值上时,& 和 | 和 ^ 运算符也会得到一个布尔值,而 ~ 会报错
    3. 与 C 语言不一样的是,Java 还有 >>> 位移运算符,该运算符会用 0 填充高位,并且 >> 位移运算符明确用符号位填充高位不同

3.6 字符串

Java 字符串就是 Unicode 字符串序列。如,串 “java\\u” 就是由5个 Unicode 字符 j、a v、a 和 TM 组成的。

接下来稍微介绍一下 String 类的一些方法

  1. 提取字串

    String 类的 substring 方法可以从一个较大的字符串提取出一个字串,如

    String str = "helloworld";
    String s = str.substring(0,5);
    // s 就会为 "hello"
    

    在 substring 中,是从0开始计数的,并且第二个参数是不想复制的第一个位置(就是左闭右开啦)

  2. 拼接

    • Java 语言使用 + 号连接两个字符串,如

      String str1 = "hello";
      String str2 = "world";
      String s = str1 + str2;
      // 上述代码将 "helloworld" 赋值给变量 message
      
    • 将一个字符串与一个非字符串的值进行拼接时,后者被转换成字符串,如

      int age = 18;
      String str = "i am";
      String s = str + age;
      

      只不过如果有几个非字符串的值相加再加一个字符串,就先进行运算,再进行拼接

    • 可以使用静态 join 方法,把多个字符串放在一起,用一个界定符分隔开,如

      String all = String.join(" / ","s","M","L","XL");
      // 结果 all 为 "S / M / L / XL"
      
  3. 不可变字符串

    由于 String 类没有提供用于修改字符串的方法,所以在 Java 文档中将 String 类对象称为不可变字符串。而如果要将一个字符修改时,Java 中可以这样做

    String str = "helloworld";
    str = str.substring(0,5) + "java";
    // 这样就可以将 "helloworld" 修改成 "hellojava" 了
    

    并且不可变字符串有一个优点:编译器可以让字符串共享

  4. 检测字符串是否相等

    使用 equals 方法检测两个字符串是否相等,如

    s.equals(t);
    // 如果字符串 s 和 t 相等,则返回 true,否则返回 false
    

    如果要不区分大小写来检测字符串是否相等,可以使用 equalsIgnoreCase,如

    "Hello".equalsIgnoreCase("hello");
    

    注意:不要使用 == 检测两个字符是否相等,因为这个运算符只能够确定两个字符串是否放置在同一个位置上。(如果字符串放在同一位置则肯定相等,但是完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上)

    也可以使用 compareTo 方法 类似于 C 语言的 strcmp 进行比较,如

    if(s.compareTo(t)==0) ...
    
  5. 空串 与 Null 串

    1. 空串 “” 是长度为0的字符串。可以使用一下代码检查一个字符串是为空,如
    if(str.length() == 0)
    // 或
    if(str.equals(""))
    

    空串是一个 Java 对象,有自己的串长度(0)和内容(空)

    1. Null 串是 String 变量中存放一个特殊值名为 null 的串,这表示目前没有任何对象与该变量关联。可以使用一下代码检查一个字符串是为 null,如
    if(str == null)
    
    1. 如果要检测一个字符串既不是 null 串也不是空串,则使用如下代码
    if(str != null && str.length() != 0)
    

    但要注意要检查 str 不为 null。

  6. 构建字符串

    如果需要用许多小段的字符串构建一个字符串,可以用下面代码

    // 首先构建一个空的字符串构建器
    StringBuilder builder = new StringBuilder();
    //当每次添加一部分内容时就调用 append 方法
    builder.append(str);	// str 为在原字符后面新增的字符串部分
    //最后当构建字符串时就调用 toString 方法,就可以得到一个 String 对象
    String s = builder.toString();
    

注意

Java 没有内置的字符串类型,而是在标准 Java 类库中提供了一个预定义类,叫做String。

3.7 输入输出

  1. 读取输入

    想要通过控制台进行输入

    1. 构造一个 Scanner 对象,并与”标准输入流“ System.in 关联

      Scanner in = new Scanner(System.in);
      
    2. 接下来就可以使用 Scanner 类的各种方法实现输入操作,如

      int a = in.nextInt();			//读入一个整数
      double b = in.nextDouble();		//读入一个浮点数
      boolean c = in.nextBoolean();	//读入一个布尔值
      String s = in.next();			//读入一个字符串,遇到空格结束
      String str = in.nextLine();		//读入一行字符串
      
    3. 最后在程序的最开始添加一行

      import java.util.*;
      

      因为 Scanner 类定义在 java.util 包中

  2. 格式化输出

    在 Java 中,格式化输出类似于 C 语言的 printf,如

    int a = 10;
    System.out.printf("%d\\n",a);
    

    但是与 C 语言肯定也是有不同的,但基本用法就是上面的形式,使用时遇到不熟悉的直接翻阅书籍查找就好

  3. 文件输入与输出

    • 想要对文件进行读取,就需要一个用 File 对象构造一个 Scanner 对象,如

      Scanner in = new Scanner(Paths.get("myfile.txt"),"UTF-8");
      

      如果文件名中包含反斜杠符,就需要在每个反斜杠前再额外加一个反斜杠,如 "c:\\ \\mydirectory\\ \\myfile.txt"

      再就可以利用第一点介绍的任何一个 Scanner 方法对文件进行读取

    • 想要写入文件,就需要构造一个 PrintWriter 对象,如

      PrintWriter out = new PrintWriter("myfile.txt","UTF-8");
      

      如果文件不存在就会创建该文件。再就可以像输出到 System.out 一样使用输出的方法

以上是关于Java 核心技术卷I 读书笔记的主要内容,如果未能解决你的问题,请参考以下文章

java数据结构之HashSet和HashMap(java核心卷Ⅰ读书笔记)

Java核心技术读书笔记11-6 Java AIO(NIO 2.0)

Java核心技术读书笔记11- 1 Java流与读写器

Java核心技术读书笔记12-Java SE 8引入的流

[读书笔记]java核心技术

《Java核心技术》 -- 读书笔记 ① - 预热