子串
String类的substring方法可以从一个较大的字符串提取出一个子串。
拼接
Java允许使用 + 号连接两个字符串。
当将一个字符串和一个非字符串进行拼接时,后者被转换为字符串。(任何一个Java对象都可以转换成字符串)
不可变字符串
String类对象称为不可变字符串。
String类没有提供用于修改字符串的方法。如果需要修改,可以先提取需要的字符,然后再拼接上替换的字符串。
诚然,通过拼接来创建一个新字符串的效率确实不高。但是,它却有一个有点:编译器可以让字符串共享。·
检测字符串是否相等
可以使用equals方法检测是否相等。
想要不区分大小写检测两个字符串是否相等,可以使用equalsIsIgnoreCase方法。
一定不能使用 == 运算符检测两个字符串是否相等。这个运算符只能够确定两个字符串是否放置在同一个位置上。因为完全有可能将内容相同的多个字符串放在不同的位置上。
注:如果虚拟机始终将相同的字符串共享,就可以使用 == 运算符检测是否相等。但实际上只有字符串常量是共享的,而 + 或 substring 等操作产生的结果并不是共享的。因此,千万不要用 == 运算符测试字符串的相等性,以免出现糟糕的bug。
空串与Null串
空串""是长度为0的字符串。
Null串表示目前没有任何对象与该变量关联。
很多时候要检查一个字符串既不是null也不为空串,我们首先要检查str不为null。如果我们在一个null值上调用方法,会出现错误。
难点:代码点与代码单元
Java字符串由char序列组成。char数据数据类型是一个采用UTD-16编码表示Unicode代码点的代码单元。大多数常用的Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。
length方法返回采用UTF-16编码表示的给定字符串所需要的代码单元数量。例如:
String greeting = "Hello";
int n = greeting.length(); // is 5.
想要得到实际的长度,即代码点数量,可以调用:
int cpCount = greeting.codePointCount(0, greeting.length());
想得到第i个代码点,应该使用下列语句:
int index = greeting.offsetByCodePoiint(0, i);
int cp = greeting.codePointAt(index);
为什么会对代码单元如此大惊小怪?请考虑下列语句: *Ƶ is the set of integers* 使用UTF-16编码表示Ƶ需要两个代码单元。调用 *char ch = sentence.charAt(1)* 返回的不是空格,而是第二个代码单元Ƶ。为了避免这种情况的发生,请不要使用char类,这太低级了。
如果想要遍历一个字符串,并且依次査看每一个代码点,可以使用下列语句:
int cp = sentence.codePointAt(i);
if(Character.isSupplementaryCodePoint(cp)){
i += 2;
} else {
i++;
}
codePointAt方法能够辨别一个代码单元是辅助字符的第一部分还是第二部分,并能够返回正确的结果。
可以用下列语句实现回退操作:
i--;
if(Character.isSurrogate(sentence.charAt(i))) {
i--;
}
int cp = sentence.codePointAt(i);
构建字符串
每次连接字符串,都会构建一个新的String对象,既耗时,又浪费空间。而使用StringBuilder类就可以避免这个问题的发生。
StringBuilder builder = new StringBuilder();
每次需要添加一部分内容时,就调用append方法:
builder.append(ch);//appends a single character
bulider.append(str);//appends a string
在需要构建字符串时就调用toString方法,将可以得到一个String对象。