Java基础笔记(二)--数据类型、运算符、控制语句、数组、字符串
数据类型
基本数据类型
基本数据类型有 4 大类,共 8 种:
-
整型:byte、short、int、long
-
浮点型:float、double
-
字符型:char
-
布尔型:boolean
整型
Java 中的整数都是有符号的,且 Java 默认的整型是 int 型。long 型需要在数值后面加 l 或 L 注明。
long l = 15L; // long 型整数
浮点型
Java 默认的浮点型是 double 型。float 型需要在数值后加 f 或 F 注明。
float f = 1.23F;
数字的表示方式
二进制:以 0b 或 0B 为前缀
八进制:以 0 为前缀
十六进制:以 0x 或 0X 为前缀
十进制的指数形式:
int i = 336; int b = 3.36e2; // 3.36 x 10^2
字符类型
Java 字符采用双字节 Unicode 编码,占两个字节(16 位)。因此可以使用十六进制(无符号)编码形式表示字符。
字符 ‘A’ 的 Unicode 编码为 ‘\u0041’,因此
char a2 = 'A'; char a2 = '\u0041'; // 两者表示同一个字符
转义字符也是字符:
布尔类型
布尔型只有两个值:true 和 false。
数值转换
自动类型转换
小范围数据类型可以自动转换为大范围数据类型。
强制类型转换
强制类型转换是在变量或常量之前加上“(目标类型)”实现。
int i = 10; byte b = (byte) i; float c = i / 3; // 输出 3.0,因为 i 和 3 都是 int 型,计算出结果是小数,小数会被转换为 int 型,截去小数部分,得到 int 型结果。又因为 c 是 float 型,int 型结果转换为 float 型 float d = (float)i / 3; // 输出 3.333333,i 被强制转换为 float 型,然后 3 也会从 int 型自动转换为 float 型。计算出的结果本身就是小数,不会截去小数部分,按 float 型要求,保留小数点后 6 位数字
引用类型
引用类型包括:类、接口、数组。
运算符
算术运算符
一元算术运算符
二元算数运算符
位运算符
无符号右移 >>> 运算符仅被允许用在 int 和 long 型数据上。如果用在 short 和 byte 型数据上,则会在位移前自动转换为 int 型。
控制语句
分支语句
-
if、if-else、else-if 结构
-
switch 语句。switch 语句中的判断表达式的计算结果只能是 byte、short、int、char 类型。
循环语句
while、do-while、for 三种循环结构。
Java 5 之后提供了一种专门用户遍历集合的 for 循环——for-each 循环。
跳转语句
Java 中有 4 种跳转语句:break、continue、throw、return。
break
break 有两种使用方式:带有标签和不带标签。不带标签的 break 语句使程序跳出所在层的循环体(离 break 最近的内循环),带有标签的 break 语句使程序跳出标签指示的循环体。
for(int i = 1; i < 5; i++) { for(int j = 1; j < 5; j++) { if(j == 3) { break; // 跳出内层循环,外层循环继续 } System.out.println(i + "-" + j); } } labelTest: // 标签名 for(int i = 1; i < 5; i++) { for(int j = 1; j < 5; j++) { if(j == 3) { break labelTest; // 跳出指定循环层 } System.out.println(i + "-" + j); } }
continue 语句
continue 语句用于跳过本次循环,进行下次循环。continue 语句有两种使用方式:带标签和不带标签。
不带标签:跳过最近的循环层的本次循环。
带标签:跳过指定循环层的本次循环。
for(int i = 1; i < 5; i++) { for(int j = 1; j < 5; j++) { if(j == 3) { continue; // 跳出内层循环,外层循环继续 } System.out.println(i + "-" + j); } } labelTest: // 标签名 for(int i = 1; i < 5; i++) { for(int j = 1; j < 5; j++) { if(j == 3) { continue labelTest; // 跳出指定循环层 } System.out.println(i + "-" + j); } }
数组
一维数组
声明数组:
元素数据类型[] 数组名;
元素数据类型 数组名[];
例:
int[] a; // 推荐此种方式 int a[];
数组声明完成后,长度还不确定。JVM 还未给数组分配内存空间。
数组初始化
静态初始化
int[] intArr; intArr = {1, 2, 3};
亦可在声明数组的同时进行初始化:
int[] intArr = {1, 2, 3};
动态初始化
int[] intArr; intArr = new int[3];
亦可在声明数组同时进行初始化:
int[] intArr = new int[3];
动态初始化使用 new 运算符分配指定长度的内存空间。
多维数组
声明二维数组:
元素数据类型[][] 数组名;
元素数据类型 数组名[][];
元素数据类型[] 数组名[];
二维数组初始化
静态初始化
int[][] intArr = {{1, 2}, {3, 4}, {5, 6}};
动态初始化
int[][] intArr = new int[2][3];
不规则数组
静态初始化不规则数组
int[][] intArr = {{1, 2}, {3}};
动态初始化不规则数组
int[][] intArr = new int[2][]; intArr[0] = new int[3]; intArr[1] = new int[1];
字符串
Java 中的字符串由双引号引起。Java 中字符采用 Unicode 编码,所以 Java 字符串可以包含中文等亚洲字符。
单个字符使用双引号引起也是字符串 “” 表示空字符串,不是 null。null 不占内存空间,空字符串会占内存空间。
Java SE 提供了三个表示字符串的类:
String: 表示不可变字符串
StringBuffer 和 StringBuilder: 表示可变字符串
不可变字符串
不可变字符串类 String 属于 java.lang 包. 使用该类创建字符串的构造方法如下:
-
String(): 创建空字符串对象
-
String(String original): 使用字符串常量创建并初始化一个新的 String 对象
-
String(StringBuffer buffer): 使用 StringBuffer 对象创建一个 String 对象
-
String(StringBuilder builder): 使用 StringBuilder 对象创建一个 String 对象
-
String(byte[] bytes): 使用平台默认的字符集解码指定的 byte 数组, 通过 byte 数组创建并初始化一个 String 对象
-
String(char[] chars): 使用字符数组创建一个 String 对象
-
String(char[] chars, int offset, int count): 使用字符数组的子数组创建一个 String 对象; offset 参数是子数组第一个元素的索引, count 参数是子数组的长度.
示例:
String s1 = new String(); String s2 = new String("Hello World"); String s3 = new String("\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064"); byte[] bytes = {97, 98, 99}; String s4 = new String(bytes); char[] chars = {'a', 'b', 'c', 'd', 'e'}; String s5 = new String(chars); String s6 = new String(chars, 0, 3);
字符串池
Java 中的不可变字符串 String 常量, 采用字符串池 ( String Pool ) 管理技术, 字符串池是一种字符串驻留技术. 采用字符串常量赋值时, 会现在字符串池中查找字符串常量, 如果已经存在该字符串常量, 使用引用赋值给变量, 否则创建字符串常量, 并放入池中. 但此原理不适用于 new 所创建的字符串对象.
示例:
String s9 = "Hello"; String s10 = "Hello"; String s7 = new String("Hello"); String s8 = new String("Hello"); System.out.println(s9 == s10); // true System.out.println(s7 == s8); // false System.out.println(s7 == s9); // false
字符串拼接
String 字符串虽然不可变, 但可以通过+运算符或 String 的concat(String str)拼接产生一个新的 String 字符串.
+: 可拼接任何类型数据生成新 String 字符串.
concat(String str): 只能拼接 String 类型字符串.
示例:
String s1 = "Hello"; String s2 = s1 + ' '; // +可以拼接字符串 String s3 = s1.concat(" "); // concat只能拼接String字符串
字符串查找
字符串本质是字符数组, 因此它也有索引, 索引从 0 开始.
String 类提供了indexOf和lastIndexOf方法用于字符或字符串查找.
indexOf:
-
int indexOf(int ch): 从前往后搜索, 返回字符 ch 第一次出现的索引.
-
int indexOf(int ch, int fromIndex): 从指定索引开始搜索, 返回字符 ch 第一出现时的索引.
-
int indexOf(String str): 从前往后搜索, 返回 String 第一次出现时的索引.
-
int indexOf(String str, int fromIndex): 从指定索引开始搜索, 返回 String 第一次出现时的索引.
lastIndexOf:
-
int lastIndexOf(int ch): 从后往前搜索, 返回字符 ch 第一次出现的索引. 失败时返回 -1.
-
int lastIndexOf(int ch, int fromIndex): 从指定索引开始从后往前搜索, 返回字符 ch 第一次出现的索引. 失败时, 返回 -1.
-
int lastIndexOf(String str): 从后往前搜索, 返回字符 ch 第一次出现的索引. 失败时, 返回 -1.
-
int lastIndexOf(String str, int fromIndex): 从指定索引开始从后往前搜索, 返回字符 ch 第一次出现的索引. 失败时, 返回 -1.
字符串比较
String 类提供了比较字符串内容、大小、前缀、后缀等的操作
内容比较
boolean equals(Object anObject): 比较两个字符串是否相等.
boolean equalsIgnoreCase(String anotherString): 忽略大小写比较两个字符串是否相等.
比较大小
int compareTo(String anotherString): 按字典顺序比较两个字符串.相等时返回 0, 大于时返回正数, 小于时返回负数.
int compareToIgnoreCase(String str): 忽略大小写比较大小.
比较前缀和后缀
boolean endsWith(String suffix): 检查字符串是否以指定字符串结束.
boolean startsWith(String prefix): 检查字符串是否以指定字符串开始.
其他:
String trim(): 去除字符串两端的空格.
String toLowerCase(): 转换为小写字符串.
String toUpperCase(): 转换为大写字符串.
字符串截取
String 类的字符串截取方法主要如下:
String subString(int beginIndex): 从指定索引开始截取字符串到最后.
String subString(int beginIndex, int endIndex): 从指定索引 beginIndex 开始截取字符串, 到索引 endIndex 为止. 但不包括索引 endIndex 处的字符.
可变字符串
可变字符串在进行追加、删除、修改、插入和拼接等操作时不会产生新的对象.
StringBuffer 和 StringBuilder 都是可变字符串类, 中文翻译为 “字符串缓冲区”.
StringBuffer 和 StringBuilder 具有完全相同的 API, 即构造方法和普通方法等内容完全相同. 区别在于:
-
StringBuffer 是线程安全的, 支持线程同步. 但在单线程环境下会影响效率;
-
StringBuilder 是单线程的, 线程不安全, 但执行效率高.
以下方法介绍以 StringBuilder 为主, StringBuffer 的内容相同.
构造方法
-
StringBuilder(): 创建字符串内容为空的 StringBuilder 对象, 初始容量默认为 16 个字符.
-
StringBuilder(CharSequence seq): 指定 CharSequence 字符串创建 StringBuilder 对象. CharSequence 接口类型, 它的实现类有: String、StringBuilder 和 StringBuffer 等, 所以 seq 可以是 String、StringBuffer 和StringBuilder 等类型.
-
StringBuilder(int capacity): 创建字符串内容为空的 StringBuilder 对象, 初始容量由参数 capacity 指定.
-
StringBuilder(String str): 指定 String 字符串创建 StringBuilder 对象.字符串长度和字符串缓冲区容量不同. 前者指在字符串缓冲区目录所包含的字符串长度, 通过length()获取; 后者指缓冲区最大所能容纳的字符数, 通过capacity()获取. 当容纳的字符数超过这个长度时, 字符串缓冲区会自动扩容, 但这是以牺牲性能为代价.
字符串追加
StringBuilder 提供了append方法进行字符串追加. 该方法有很多重载方法, 返回值仍是 StringBuilder.
示例:
StringBuilder s = new StringBuilder("Hello"); Object o = null; s.append(" World"); s.append(false); // 转换为"false" s.append(123); s.append(o); // 空对象转换为"null"
字符串插入、删除和替换
-
StringBuilder insert(int offset, String str): 在字符串缓冲区指定索引处之前插入 str. 该方法有多个重载方法, 支持插入任何类型数据.
-
StringBuilder delete(int start, int end): 在字符串缓冲区, 删除从索引 start 到索引 end-1 的字符.
-
StringBuilder replace(int start, int end, String str): 在字符串缓冲区中, 使用 str 替换从索引 start 到索引 end-1 处的字符.