Java基础.png
简化版脑图


特性

  • 简单性、面向对象、分布式、健壮性、安全性、体系结构中立、可移植性、解释型、高性能、多线程、动态性

基础

注释

  • 单行注释://
  • 多行注释:/ /
  • 文档型注释:/* /

数据类型

整型

类型 存储需求 取值范围
int 4字节 -2^31 到 2^31 -1
short 2字节 -2^15 到 2^15 -1
long 8字节 -2^63 到 2^63 -1
byte 1字节 -2^7 到 2^7 - 1
  • Tips:

    • 长整型数值有一个后缀:大写或小写的L,如 4000000000L
    • 十六进制数值有一个前缀 0x 或 0X,如 0xCAFE
    • 八进制有一个前缀0,如 010对应八进制中的8
    • Java7开始,加上前缀 0b 或 0B 可以写二进制数,如 0b1001表示9
    • Java7开始,可为数字字面量加下划线,如 1_000_000 (或0b1111_0110_0010_0100_0000),表示一百万,Java编译器会去除这些下划线

      浮点类型

      | 类型 | 存储需求 | 取值范围 | | —- | —- | —- | | float | 4字节 | 约 ±3.4028235e+38f (有效位数为6~7位) | | double | 8字节 | 约 ±1.7976931348623157e+308 (有效位数为15位) |
  • 特殊浮点值

    • 正无穷大:Double.POSITIVE_INFINITY
    • 负无穷大:Double.NEGATIVE_INFINITY
    • NaN (不是一个数字):Double.NAN,可通过 Double.isNaN方法校验
  • Tips:

    • float类型的数值有一个后缀:大写或小写F,如 3.14F
    • double类型的数值有一个后缀:大写或小写D,如3.14D
    • 没有后缀浮点值(如 3.14)默认为double类型(即默认为 3.14D)
    • 本质上浮点数值采用二进制系统表示,因此无法精确地表示一些分数,如 1/ 10(就如同十进制无法精确地表示 1/ 3一样);当使用浮点数进行计算时,不允许有舍入误差就需要用 BigDecimal类
      • BigDecimal类实现原理是:将小数扩大n被(如10^n),同时结合指数,来得出没有精度损失的结果(参考链接1参考链接2

        char类型

  • char c = ‘A’; // char类型的字面量值要用单引号括起来,’A’是编码值为65对应的字符常量,与字符串”A”不同,需要区分开

    boolean类型

  • 有两个值:true 和 false,常用于条件判断

变量

  • 变量名:必须以字母开头,可由大小写字母、数字、下划线(_)、美元符($)构成;变量名不能为Java的保留字(如class, this, for, do等等)
  • 初始化变量语法:类型 变量名;(如 int num;)
  • 使用关键字final就变为常量:final 类型 常量名 = 常量值;(如 final int MAX_NUM = 1;)
    • 常量名最好使用全大写加下划线分割

运算符

算数运算符

运算符 名称 备注
+
-
*
/ 整数被0除将会产生异常,浮点数被0除将得到无穷大或NaN
% 求余(取模)

二元运算符

  • 一般,把运算符放在 = 号左边,如 += 或 -= 或 *= 或 /= 或 %= 或 &= 或 |= 或 ^= 或 <<= 或 >>= 或 >>>=
  • 示例:x += 4; 等价于 x = x + 4;

    自增与自减运算符

  • 自增:++

    • ++放变量左边,先自增后运算
    • ++放变量右边,先运算后自增
    • 示例:
      • int a = 1; int b = a++; // 结果a为2,b为1
      • int a = 1; int b = ++a; // 结果a为2,b为2
  • 自减:—
    • 同理自增
  • Tips:
    • 只适用于整型或是浮点类型的已进行赋值操作的变量
      • good case: int i = 1; i++;
      • bad case: int i; i++; String s = "ok"; s++;

        关系运算符

        | 关系运算符 | 名称 | 备注(以:a 关系运算符 b 说明) | | —- | —- | —- | | == | 校验相等 | a == b,当两边相等结果为true,否则为false | | != | 校验不等 | a != b,当两边不等结果为true,否则为false | | < | 小于 | a < b,当a小于b时结果为true,否则为false | | > | 大于 | a > b,当a大于b时结果为true,否则为false | | <= | 小于等于 | a <= b,当a小于或等于b时结果为true,否则为false | | >= | 大于等于 | a >= b,当a大于或等于b时结果为true,否则为false | | && | 与 | 条件1 && 条件2,当条件1,2都为true时结果为true,否则为false | | || | 或 | 条件1 || 条件2,当条件1,2有一个为true时结果为true,否则为false | | ! | 非 | !条件,当条件为true时,结果为false,否则为true |

位运算符

位运算符 名称 备注(都作用于二进制数值)
& 按位与运算符 1&1=1、1&0=0、0&1=0、0&0=0
| 按位或运算符 1|1=1、1|0=1、0|1=1、0|0=0
^ 按位异或运算符 1^1=0、1^0=1、0^1=0、0^0=0
~ 按位取反运算符 ~1=0、~0=1
<< 左移运算符
>> 带符号右移运算符
>>> 无符号右移运算符

括号与运算符优先级

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

字符串

String类

  • 标准Java类库中提供,每个用双引号括起来的字符串都是String类的实例
  • 如:String str = “hello”;

    子串

  • String类提供substring方法可以从一个字符串中提取出一个子串

  • 如:String str = “hello”; String s = str.substring(0, 3);
  • substring第一个参数为开始复制的位置,第二参数为不想复制的第一个位置,因此上面要复制的为str的第0,1,2位

    拼接

  • String str = “hello”; String str2 = “world”; String all = str + str2;

    不可变字符串

  • String类对象本身就被称为不可变字符串

    检测字符串相等

  • 使用equals()方法

  • 如:str1.equals(str2)方法

    空串与Null串

  • str.length() == 0 或 str.equals(“”)为true则为空串

  • str == null 检查一个字符串是否为空

    码点与代码单元:

  • Java字符串由char值序列组成

    • String str = “abc”;
    • 本质上等同于:char data[] = {‘a’, ‘b’, ‘c’}; String str = new String(data)
  • 可使用charAt(n)方法来访问位置n的代码单元(n介于0 ~ str.length - 1之间)

    • 如:String str = “hello”; char second = str.charAt(1); // seconde的值为e

      构建字符串

  • 当出现需要多个短的字符串构建一个长的字符串时,使用字符串拼接方式效率太低(不断创建新的String对象),这种场景推荐使用StringBuilder

    1. String str1 = "haha";
    2. String str2 = " ok!";
    3. StringBuilder builder = new StringBuilder();
    4. builder.append(str1); // 调用append方法拼接
    5. builder.append(str2);
    6. String longStr = builder.toString(); // 调用toString方法获得整串字符串

控制流程

块作用域

  • 块(即复合语句)是指由一对大括号括起来的若干简单的Java语句
  • { … }

    条件语句

  • if…else

  • if…else if…else

    循环

  • for

  • for each:for(variable : collection) statement
  • while
  • do…while
  • switch
  • break, continue (中断流程)

大数值

当基本的整数和浮点精度无法满足需求时,可以考虑使用 java.math中的两个类:BigInteger 和 BigDecimal,这两个类可处理包含任意长度数字序列的数值

  • BigInteger类实现了任意精度的整数运算
  • BitDecimal类实现了任意精度的浮点数运算

通常使用静态的valueOf方法将普通数值转换成大数值

  1. // BigInteger示例
  2. int a = 100;
  3. int b = 200;
  4. BigInteger bigA = BigInteger.valueOf(a);
  5. BigInteger bigB = BigInteger.valueOf(b);
  6. BigInteger c = bigA.add(bigB);
  7. // BigDecimal示例
  8. double a2 = 100.0;
  9. double b2 = 200.0;
  10. BigDecimal bigDecimalA = BigDecimal.valueOf(a2);
  11. BigDecimal bigDecimalB = BigDecimal.valueOf(b2);
  12. BigDecimal c2 = bigDecimalA.add(bigDecimalB);

数组

数组是一种数据结构,用来存储同一类型值的集合。通过一个整型下标可以访问数组中的每一个值。如a是一个整型数组,a[i]就是数组下标为i的整数

  • 声明语法:数据元素类型[] 变量名;
  • 初始化语法:数据元素类型[] 变量名 = new 数据元素类型[数组长度]

    1. int[] a; // 声明整型数组a
    2. int[] b = new int[100]; // 声明整型数组b并初始化

    数组初始化以及匿名数组

  • 直接创建数组对象并同时赋予初始值:int smallPrimes = { 2, 3, 4 };

  • 直接初始化一个匿名数组:new int[] { 2, 3, 4 };
  • 注意:Java允许数组长度为0,需要区分开数组长度为0以及null的区别

    • 长度为0表示数组没有长度
    • null代表数组内无任何元素,但却有长度

      数组拷贝

  • Arrays类的copyOf方法

    1. int[] nums = { 1, 2, 3 };
    2. int[] copyNums = Arrays.copyOf(nums, nums.length);
    3. // Arrays.copyOf方法第一个参数时要拷贝的数组,第二个参数是新数组的长度

    数组排序

  • Arrays类的sort方法(该方法使用了优化的快速排序算法)

    多维数组

    1. // 声明一个二维数组
    2. int[][] nums;
    3. // 初始化一个二维数组
    4. int[][] newNums = new int[3][3];
    5. // 初始化一个二维数组并赋值
    6. int[][] numbers = {
    7. {1, 2, 3},
    8. {4, 5, 6},
    9. {7, 8, 9}
    10. };
    11. // 访问方法同一维数组类似,直接使用下标即可 numbers[行下标][列下标]
    12. int oneNumber = numbers[1][1]; // oneNumber值为5

    不规则数组

    1. // Java本质上只有一维数组,所谓的多维数组只是在一维数组中的每个位置再嵌套一个数组
    2. int[][] nums = new int[3][];
    3. for (int i = 0; i < 3; i++) {
    4. nums[i] = new int[i+1];
    5. }
    6. /* 以上面的程序为例,最后输出的是类似下面的不规则数组
    7. {
    8. { 1 },
    9. { 1, 2 },
    10. { 1, 3, 3 },
    11. };
    12. */

提问环节

  1. BigDecimal类是如何解决浮点类型数值的计算精度问题的?
  2. BigInteger类又是如何解决整型数值计算的精度问题的?
  3. 涉及多个短的字符串拼接成一个长字符串时,为什么推荐使用StringBuilder类?它又是怎么实现字符串拼接的呢?
  4. 数组拷贝中,Arrays类的copyOf方法是如何实现的?它是深克隆还是浅克隆呢?
  5. 数组排序中,Arrays类的sort方法又是如何实现的呢?