Java核心技术1-基本程序设计

  |  

摘要: 本文是《Java核心技术 10th》中基本程序设计的要点总结

【对算法,数学,计算机感兴趣的同学,欢迎关注我哈,阅读更多原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:算法题刷刷
我的知乎:潮汐朝夕
我的github:FennelDumplings
我的leetcode:FennelDumplings


本文是《Java核心技术1》第10版 【Chap3 基本程序设计】 的要点总结。


8种基本数据类型

整型

  • int: 4字节
  • short: 2字节
  • long: 8字节
  • byte: 1字节

Java没有任何无符号的 int, long, short, byte

浮点型

  • float: 4字节
  • double: 8字节

表示溢出和出错的3个特殊浮点数值

正无穷
负无穷
NaN(不是一个数字)

double.isNaN 判断
不允许舍入误差,则要用 BigDecimal 类

char型

一些Unicode可以用一个 char 值描述,有的需要两个

转义序列 \u 可以出现在字符字面量或字符串中,会在解析代码前处理

Unicode

  • 码点:与一个编码表中某个字符对应的代码值
  • UTF16采用不同长度的编码表示所有Unicode码点

char类型是一个采用 UTF16编码表示的 Unicode码点的代码单元
建议不要使用 char 型(除非确实要处理 UTF16),最好用字符串

boolean

整形值和布尔值之间不能相互转换

变量

  • 声明变量时,每个变量都有一个类型
  • 保留字不可用于变量名
  • 变量初始化
    • 声明变量之后,必须用赋值语句显式初始化
  • 与C++不同的是,Java不区分变量的声明和定义
  • 常量
    • 关键字 final
    • 只能被赋值一次
    • static final 可以设置类常量

运算符

算术运算符

  • +, -, *, /, %
  • 整数被 0 除产生一个异常,浮点数被 0 除得到无穷大或 NaN
  • 数学函数
    • import java.lang.Math
    • sqrt, pow, floorMod
    • sin, cos, tan, atan, atan2
    • exp, log, log10
    • Math.E, Math.PI
  • 数值类型转换
    • 无信息丢失
      • byte -> short
      • short -> int
      • char -> int
      • int -> long
      • float -> double
      • int -> double
    • 有信息丢失
      • int -> float
      • long -> double
      • long -> float
    • 自动类型转换
      • 有一个 double,另一个转换为 double
      • 否则,有一个 float,另一个转换为 float
      • 否则,有一个是 long,另一个转换为 long
      • 否则,两个都转换为 int
    • 强制类型转换
      • 丢失信息的转换,需要 cast
      • Math.round
      • 转换后超出了目标类型的表示范围,则会截断
  • 扩展赋值运算符
    • +=, -=, *=, /=, %=
  • 自增运算符
    • ++, --
    • 前缀形式和后缀形式

关系运算符

  • ==, !=, <, >, <=, >=
  • &&, ||

三元运算符

  • cond ? expr1 : expr2

位运算符

  • &, |, ^, ~
  • <<, >>
  • >>> 用 0 填充高位;>> 用符号为填充高位
  • 没有 <<<
  • C++ 中 >> 对于负数生成的结果依赖具体实现

运算符优先级

  • [] . ()(方法调用)
  • ! ~ ++ -- +(一元) -(一元) ()(强制类型转换) new
    • 从右向左结合
  • * / %
  • + -
  • << >> >>>
  • < <= > >= instanceof
  • == !=
  • &
  • ^
  • |
  • &&
  • ||
  • ?: (从右向左结合)
  • = += -= *= /= %= |= &= ^= <<= >>= >>>= (从右向左结合)

枚举类型

  • 变量取值只在有限集合内
  • 枚举类型的变量只能存储给定的某个枚举值,或 null 值

控制流

  • 没有 goto,但 break 可以带标签,其它基本与 C++ 基本一样
  • 块作用域
    • 块确定了变量的作用域
    • Java不能在嵌套的两个块中声明同名变量,C++中是内层覆盖外层
  • 条件语句
  • 循环
    • while
    • for
  • 多重选择 swtich
    • 从与选项值相匹配的case标签处开始执行直到遇到break语句
    • 没有相匹配的case标签,而有default子句,就执行这个子句。
    • 如果在case分支语句的末尾没有break语句,那么就会接着执行下一个case分支语句。
    • case标签
      • 类型为char、byte、short或int的常量表达式
      • 枚举常量
      • 字面值常量
  • 中断
    • 普通 break 和 continue
    • 带标签的break
      • Java可以用带标签的break,跳出多重嵌套的循环。
      • 标签必须放在希望跳出的最外层循环之前,并且必须紧跟一个冒号。
    • 带标签的 continue
      • 跳到与标签匹配的循环首部。

字符串

  • 概念上讲,Java字符串就是Unicode字符序列
  • Java没有内置的字符串类型,而是在标准 Java 类库中提供预定义类 String
  • 子串
    • substring
  • 拼接
    • +
    • 字符串与非字符串拼接,会先转换成字符串
    • Java任何对象都可以转换成字符串
    • join
  • 不可变字符串
    • String没有可以修改字符串的方法
    • 缺点是提取,拼接低效
    • 优点是编译器可以让字符串常量在堆中共享
    • 只有字符串常量是共享的,+ 和 substring 等操作产生的结果并不共享
  • 检测字符串是否相等
    • equals
    • equalsIgnoreCase
    • == 判断的是字符串是否在同一位置上
    • compareTo 类似于 C 语言的 strcmp
  • 空串
    • str.length() == 0 或者 str.equals(“”)
    • Java 对象,有串长度(0),和内容(空)
  • null串
    • 没有任何对象与该变量关联
    • str == null
  • 码点和代码单元
    • char类型是一个采用 UTF16编码表示的 Unicode码点的代码单元
    • length() 返回采用 UFT16 编码表示的给定字符串所需的代码单元数量
    • 要得到实际长度,也就是码点数量,用 codePointCount()
    • charAt() 返回位置 n 的代码单元
    • 获得第 i 个码点
      1
      2
      int idx = offsetByCodePoints(0, i);
      int ch = str.codePointAt(idx)
    • 由于有些UTF16表示的字符需要两个代码单元,最好不用 char 类型
    • 遍历字符串,查看每一个码点
      1
      2
      3
      4
      5
      6
      int i = 0;
      int p = str.codePointAt(i);
      if(Character.isSupplementaryCodePoint(p))
      i += 2;
      else
      i++;
    • codePoints 方法生成一个int值的流,每个int对应一个码点
      1
      int codePoints = str.codePoints().toArray();
    • 码点数组转换为字符串
      1
      String str = new String(codePoints, 0, codePoints.length);
  • String API
  • 由许多小串构建字符串
    1
    2
    3
    4
    StringBuilder builder = new StringBuilder();
    builder.append(ch);
    builder.append(str);
    String completedString = builder.toString()

输入输出

  • Scanner 读取输入
    • 构造 Scanner 对象,与标准输入流 System.in 关联
      1
      Scanner in = new Scanner(System.in);
    • 读取一行
      1
      String name = in.nextLine();
    • 取一个单词
      1
      String firstName = in.next();
    • 取一个整数
      1
      int age = in.nextInt()
    • 取一个浮点数
      1
      int age = in.nextDouble()
  • Console 读取输入
    • Scanner 不适合从控制台读密码
      1
      2
      3
      Console cons = System.console();
      String username = cons.readLine("User Name: ");
      char[] passwd = cons.readPassword("Password: ");
    • 为了安全起见,返回的密码存放在一维字符数组中,而不是字符串中。在对密码进行处理之后,应该马上用一个填充值覆盖数组元素
    • Console 只能读取一行输入。没有能读取一个单词或数值的方法。
  • 格式化输出
    • System.out.print(x)
      • 以x对应的数据类型所允许的最大非0数字位数打印输出x
    • System.out.printf(x)
      • 沿用了C语言库函数中的printf方法
      • String message = String.format(...); 创建格式化字符串而不打印输出
    • Scanner 文件输入
      • 用File对象构造一个Scanner对象
      • Scanner in = new Scanner(Paths.get(“file.txt”), “UTF-8”);
    • Scanner 文件输出
      • 用PrintWriter对象构造一个Scanner对象
      • Scanner out = new PrintWriter(“file.txt”, “UTF-8”);
    • 命令行重定向
      • java Proj < file.txt > output.txt

大数值

  • java.math.BigInteger 和 java.math.Decimal
  • 普通数值转换为大数值
    1
    BigInteger a = BigInteger.valueOf(100);
  • 与 C++ 不同,Java 没有运算符重载
  • add, multiply, subtract, divide, mod, compareTo, valueOf

数组

数组是一种数据结构,存储同一类型值的集合,且可通过下标访问

Arrays API

声明

1
int[] a;

初始化

1
a = new int[100];
  • 数字数组,所有元素都初始化为0。
  • boolean数组,初始化为false。
  • 对象数组,初始化为一个特殊值null
1
a = {2, 3, 5, 7};
  • 初始化匿名数组
1
new int[] {2, 3, 5, 7}

可以用在方法的返回值

  • 长度为 0 的数组
1
new int[0]

长度

1
a.length

数组一旦创建,不能再改变大小,如果要改变大小,用数组列表 ArrayList

for each 循环

1
for(variable: collection) statement

collection 是实现了 Iterable 接口的类对象

数组拷贝

1
int[] b = a;
  • 在Java中,允许将一个数组变量拷贝给另一个数组变量。
  • 这时,两个变量将引用同一个数组
  • 如果要将所有值拷贝到新数组,用 Arrays 类的 copyOf 方法

命令行参数

  • main 接收一个字符串数组 args
  • 与C++不同,程序名并不在args数组中

数组排序

1
Arrays.sort()

快速打印

1
System.out.println(Arrays.ToString(a));

多维数组

  • 声明
    1
    double[][] a;
  • 初始化
    1
    a = new double[100][100]
  • for each
    1
    2
    3
    for(double[] row: a)
    for(double val: row)
    ...
  • 快速打印
    1
    System.out.println(Arrays.deepToString(a));
  • 不规则数组
    • Java实际上没有多维数组,只有一维数组。多维数组被解释为“数组的数组。
    • 由于多维数组实际上是一维数组,可以方便地构造不规则数组

Java 数组类似于 C++ 中分配在堆上的数组指针

  • 一维
    • Java: double[] a = new double[10];
    • C++: int* a = new int[100];
  • 二维
    • Java: double[][] a = new double[10][5];
    • C++: double** a = new double*[10];

Share