本文主要介绍一些关于Java字符串的易错易忘的知识点,并非系统完整介绍,如有在意,还请见谅。
一、字符串的概念
1.字符串到底是什么
💭:字符串的概念有什么好说的?😪
💬:这里不是的简单重复其一般性概念哦,而是专门指明Java中字符串的本质
在Java中,其实Java字符串就是Unicode字符序列。String 并不是Java内置的基本类型,而是由标准Java类库中提供的一个预定义类。
2.区别 码点 和 代码单元
🔔概念解释:
码点是指 一个编码表 中的 某个字符 对应的 代码值。
Unicode的码点分为17个代码级别,第一个级别是基本的多语言级别,码点从U+0000——U+FFFF,其余的16个级别从U+10000——U+10FFFF,其中包括一些辅助字符。
代码单元则是指在基本的多语言级别中,每个字符用16位表示代码单元。而辅助字符则采用一对连续的代码单元进行编码。
总之,一个码点既可以表示一个一般字符也可以表示一个辅助字符;而一个代码单元则只能表示一个一般字符,要两个代码单元才能表示一个辅助字符。
🚬 我的个人理解是:代码单元其实是一种抽象的单位1,为了方便遍历字符串中的一般字符和表示char类型字符的。
⭕️补充:如果想要了解更多关于编码的细节问题请看:
编码格式简介(ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE)
二、字符串的有趣方法
1.像切片一样获取子串
用过Python的应该知道Python有一个好用的处理字符串的方式叫做 切片,而在Java中同样有类似方法,并且规律相同,都是左闭右开。
🕑方法如下:
🕒代码实现如下:
🕓代码运行结果如下:
⭕️补充:从以上结果可以看出,substring(m,n) 方法------当m与n相等时,截取到的子串为空,并不会报错
2.拼接字符串
🔔解释:
在Java中,当一个字符串与一个非字符串的值进行拼接时,后者会被转换为字符串(其实任何一个Java对象都能转换为字符串,重写toString方法即可)而使用 + (加号)就可以拼接啦。
⭕️补充:在拼接多个字符串时,如果想要用一个界定符分隔它们,则可以使用String类的 静态join 方法
🕑方法如下:
🕒代码实现如下:
🕓代码运行结果如下:
3.处理码点和代码单元
经常使用的是获取代码单元,因为获取到代码单元经常与char字符进行比较或者其他处理,本文最后会给出一道算法题,其中就可以利用这个。
3.1获取长度
🕒代码实现如下:
public class Article {
public static void main(String[] args) {
String str = "hi\uD835\uDD46"; //hi后面的其实是辅助字符:𝕆
//获取字符串的代码单元长度
int unit_len = str.length();
//获取字符串的码点长度/码点数量
int cpCount = str.codePointCount(0,unit_len);
System.out.println("代码单元长度:"+unit_len);
System.out.println("码点长度/数量:"+cpCount);
}
}
🕓代码运行结果如下:
怎么样,是不是很有趣?😄
3.2获取索引为n处的值
🕒代码实现如下:
public class Article {
public static void main(String[] args) {
String str = "hi\uD835\uDD46";
//获取索引为1处的代码单元
char first = str.charAt(1);
//获取索引为1处的码点
int cp = str.codePointAt(1);
//有意思的是码点长度为3,但却可以取到索引3处的值;这是为什么呢?
System.out.println("代码单元:"+first);
System.out.println("码点:"+cp);
}
}
🕓代码运行结果如下:
4.将字符串转为字符数组
🕑方法如下:
🕒代码实现如下:
public class Article {
public static void main(String[] args) {
String str = "hi,windx";
char[] c = str.toCharArray();
for (int i = 0; i < c.length; i++) {
System.out.print(c[i]+" ");
}
}
}
🕓代码运行结果如下:
5.其它方法(判别前后缀、去除空白符)
5.1 判别前后缀
有时我们通常会对一个字符串的前缀或后缀进行判断,看是否满足筛选条件,此时这个方法就能够派上用处了(如果用substring()的话有时会有意想不到的Bug)。
🕑方法如下:
①前缀:
②后缀:
分别判断是否以某字符串开头、以某字符串结尾,均返回boolean类型值。
5.2 去除空白符
该方法可以删除原始字符串头部和尾部小于等于U+0020的字符或空格,同样用于对字符串进行处理。
🕑方法如下:
三、判断字符串是否相等
👉 首先要注意的是字符串是不可变的,当简单复制一个字符串时,其实是共享了同一处空间,只是复制了引用而已。
因此,
- 使用 == 运算符判断两字符串是否相等,比较的只是两字符串的地址。
- 如果要比较内容,需要使用equals()方法!而不区分大小写比较,则使用equalsIgnoreCase()方法。
⭕️补充:不论是使用 + 连接空字符串还是substring()获取子串或者进行大小写转换,都会改变字符串的地址
🕒代码测试如下:
public static void main(String[] args) {
String a = "aaa";
String b = a;
System.out.println("初始a的地址:");
System.out.println("a:"+String.class.getName() + "@" + Integer.toHexString(System.identityHashCode(a)));
a+="";
if(b==a){
System.out.println("b==a");
}
if(b.equals(a)){
System.out.println("b.equals(a)");
}
System.out.println("与空串拼接后a的地址:");
System.out.println("a:"+String.class.getName() + "@" + Integer.toHexString(System.identityHashCode(a)));
System.out.println("b的地址:");
System.out.println("b:"+String.class.getName() + "@" + Integer.toHexString(System.identityHashCode(b)));
}
🕓代码运行结果如下:
可以看到由初始的a字符串复制的b字符串的地址与其初始地址是相等的,而a在拼接空串后,其地址发生了变化,但内容值不变。
⭕️补充:空串和null是两码事,字符串可以为空串 “”,也可以赋值为null,因为它本质是一个类对象。不可以对null调用字符串方法,因此常常需要判断是否为null。
时九月十九,秋意凉,不凉少年心。