Java 的字符串
- Java 字符串就是 Unicode 字符序列。
- 字符串是由 Java 类库提供的一个预定义类 String,而不是内置的数据类型。
- 每一个用双引号括起来的字符串都是 String 类的一个实例对象。
码点与代码单元
码点就是字符串中的一个字符,代码单元就是一个十六位的编码,有的码点只需要一个代码单元即可表示,有的码点需要两个代码单元表示。
那么Java是如何判断代码单元是一个字符还是辅助平面字符的第一部分或第二部分呢?
先了解平面概念:
Unicode目前有17个平面,从第0平面(基本平面:0x0000 ~ 0xFFFF)到第16平面(0x100000 ~ 0x10FFFF);
平面就是指码点范围。
在基础平面中有0xD800 ~ 0xDBFF和0xDC00 ~ 0xDFFF两个空段,我们可以利用这两个空段来表示其它平面的码点。下面介绍计算方法:
比如露齿笑脸符号😀在第1辅助平面(0x10000 ~ 0x1FFFF)中的码点是0x1F600。
- 首先得到码点对0x10000的偏移量:
0x1F600-0x10000=0xF600
0xF600的二进制是 1111 0110 0000 0000 - 将其分成两个10位的值,前面补零。
00 0011 1101 0x03D
10 0000 0000 0x300 - 分别得到码点的第一代码单元和第二代码单元
在 0xD800 ~ 0xDBFF 范围内表示第一代码单元,偏移 0x03D 得到 0xD83D;
在 0xDC00 ~ 0xDFFF 范围内表示第二代码单元,偏移 0x300 得到 0xDE00。
让我们测试一下:
int[] point={0xD83D,0xDE00};
String str=new String(point,0,2);
System.out.print(str);
输出效果:
😀
下面介绍几个与码点相关的函数:
int codePointCount(int beginIndex, int endIndex)
返回索引区间[beginIndex,endIndex)的码点数量。
int offsetByCodePoints(int index, int codePointOffset)
返回从index偏移codePointOffset个码点的索引值。
int codePointAt(int index)
返回索引index处的码点
int codePointBefore(int index)
返回索引index的前一个码点
演示:
String str="哈哈😀哈";
System.out.println("长度:"+str.length()+",码点数:"+str.codePointCount(0,str.length()));
System.out.println("第三个码点的索引值:"+str.offsetByCodePoints(0,2));
System.out.println("第三个码点:"+str.codePointAt(2)+",第二个码点:"+str.codePointBefore(2));
char[] chars = Character.toChars(128512);
System.out.print(new String(chars));
输出效果:
长度:5,码点数:4
第三个码点的索引值:2
第三个码点:128512,第二个码点:21704
😀
子串
Java 没有提供像 C++ 一样把字符串当作字符数组来使用的方法,Java 的字符串常量被放到一个叫字符串常量池里,其是不可改变的。不过我们可以使用String类提供的substring
方法来获取子串。
substring(beg,end)
方法是复制字符串的[beg,end)
位的子串,例:
String str = "Hello, My friend!".substring(0,3); //str="Hel"
拼接
Java 允许使用通过+
号来拼接字符串。例如:
String str0 = "Hello";
String str1 = "World";
String str2 = str0 + " " + str1;
如果希望将多个字符串拼接,并使用界定符,可以使用String.join
方法来实现:
System.out.println(String.join(",","香蕉","苹果","西瓜"));
输出效果:
香蕉,苹果,西瓜
字符串是否相等
很多小伙伴在使用字符串时会习惯性地认为比较字符串用==
逻辑运算符就可以了,但 Java 中并不一定能成功。通常在 Java 中比较两个字符串是否相等使用equals
方法来实现。
==
在 Java 中实际是比较两个字符串的存储地址是否相同,在 C+++ 中重载了字符串的==
运算符。
equals
才是比较字符串值是否相等。
s==t; //如果字符串s与字符串t地址相同结果为true
s.equals(t); //如果字符串s与字符串t内容相同返回true
空串与null串
空串""
是长度为
0
0
0的字符串。
null
表示没有任何对象与该变量相连。
检查空串用:
s.quals("");
s.length()==0;
检查null
用:
s==null;
常用方法
char charAt(int index)
返回索引 index 处的代码单元,index 从
0
0
0开始。
int compareTo(String other)
按照顺序比较代码单元,返回第一个不同代码单元的差值,other 大返回负值,相同返回
0
0
0。
new String(int[] codePoints, int offset, int count)
用数组中从 offset 开始的 count 个码点构造一个字符串。
boolean equals(0bject other)
如果字符串与 other 相等, 返回 true。
boolean equalsIgnoreCase(String other)
如果字符串与 other 相等(忽略大小写),返回 true。
boolean startsWith(String prefix)
boolean endsWith(String suffix)
如果字符串以 suffix 开头或结尾,则返回 true。
int indexOf (String str)
int indexOf (String str , int fromIndex)
int indexOf (int cp)
int indexOf (int cp, int fromlndex)
返回与字符串str 或代码点 cp 匹配的第一个子串的开始位置。这个位置从索引 0 或 fromlndex 开始计算。如果在原始串中不存在str, 返回-1。
ndex)`
返回与字符串str 或代码点 cp 匹配的第一个子串的开始位置。这个位置从索引 0 或 fromlndex 开始计算。如果在原始串中不存在str, 返回-1。