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

java 吐核 java核心算法_java


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 个码点
int idx = offsetByCodePoints(0, i);
int ch = str.codePointAt(idx)
- 由于有些UTF16表示的字符需要两个代码单元,最好不用 char 类型
- 遍历字符串,查看每一个码点
int i = 0;
int p = str.codePointAt(i);
if(Character.isSupplementaryCodePoint(p))
    i += 2;
else
    i++;
- codePoints 方法生成一个int值的流,每个int对应一个码点
int codePoints = str.codePoints().toArray();
- 码点数组转换为字符串
String str = new String(codePoints, 0, codePoints.length);
StringBuilder builder = new StringBuilder();
builder.append(ch);
builder.append(str);
String completedString = builder.toString()

输入输出

  • Scanner 读取输入
  • 构造 Scanner 对象,与标准输入流 System.in 关联
Scanner in = new Scanner(System.in);
- 读取一行
String name = in.nextLine();
-  取一个单词
String firstName = in.next();
-  取一个整数
int age = in.nextInt()
-  取一个浮点数
int age = in.nextDouble()
  • Console 读取输入
  • Scanner 不适合从控制台读密码
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
  • 普通数值转换为大数值
BigInteger a = BigInteger.valueOf(100);
  • 与 C++ 不同,Java 没有运算符重载
  • add, multiply, subtract, divide, mod, compareTo, valueOf

数组

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

Arrays API

声明

int[] a;

初始化

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

可以用在方法的返回值

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

长度

a.length

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

for each 循环

for(variable: collection) statement

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

数组拷贝

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

命令行参数

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

数组排序

Arrays.sort()

快速打印

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

多维数组

  • 声明
double[][] a;
  • 初始化
a = new double[100][100]
  • for each
for(double[] row: a)
    for(double val: row)
        ...
  • 快速打印
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];