从概念上讲
,
Java
字符串就是
Unicode
字符序列
。
例如
,
串
“
Java
\
u
2122
”
由
5
个
Unicode
字符 J
、
a
、
v
、
a
和™。
Java
没有内置的字符串类型
,
而是在标准
Java
类库中提供了一个预定义类,
很自然地叫
String
。
每个用双引号括起来的字符串都是
String
类的一个实例:
String e = ""; // an empty string
String greeting = "Hello";
子串
String
类的
substring
方法可以从一个较大的字符串提取出一个子串
。
例如
:
String
greeting
=
"
Hello
"
;
String
s
=
greeting
.
substring(0,3)
创建了一个由字符
“
Hel
”
组成的字符串
。
substring
方法的第二个参数是不想复制的第一个位置
。
这里要复制位置为
0
、
1
和
2
(
从
0
到
2
,
包括
0
和
2
)
的字符
。
在
substring
中从
0
开始计数
,
直到
3
为止
,
但不包含
3
。
substring
的工作方式有一个优点
:
容易计算子串的长度
。
字符串
s
.
substring
(
a
,
b
)
的长度
为
b
-
a
。
例如
,
子串
“
Hel
”
的长度为
3
-
0
=
3
。
拼接
与绝大多数的程序设计语言一样
,
Java语言允许使用
+
号连接
(
拼接
)
两个字符串
String expletive = "Expletive";
String PC13 = "deleted";
String message = expletive + PC13;
上述代码将
“
Expletivedeleted
”
赋给变量
message
(
注意
,
单词之间没有空格
,
+
号按照
给定的次序将两个字符串拼接起来)。
当将一个字符串与一个非字符串的值进行拼接时
,
后者被转换成字符串
(
在第
5
章中可
以看到
,
任何一个
Java
对象都可以转换成字符串
)
。
int age = 13;
String rating = "PC" + age;
如果需要把多个字符串放在一起
,
用一个定界符分隔
,
可以使用静态
join
方法
:
String all = String.join(" / ", "S", "M", "L", "XL");
// all is the string "S / H / L / XL"
不可变字符串
由于不能修改 Java 字符串中的字符,所以在Java文档 String 类对象称为不可变字符串,
如同数字
3 永远是数字 3,字符串而不能修改其中的任何一个字符
当然
可以修改字符串变量 greeting, 让它引用另外一个字符串,
这就如同可以将存放
3
的数值变量改成存放
4
一样
这样做是否会降低运行效率呢
?
看起来好像修改一个代码单元要比创建一个新字符串更
加简洁
。
答案是:
也对
,
也不对
。
的确
,
通过拼接
“
Hel
”
和
“
p
!
”
来创建一个新字符串的
效率确实不高
。
但是
,
不可变字符串却有一个优点
:编译器可以让字符串共享。
为了弄清具体的工作方式
,
可以想象将各种字符串存放在公共的存储池中
。
字符串变量
指向存储池中相应的位置
。
如果复制一个字符串变量
,
原始字符串与复制的字符串共享相同
的字符
。
总而言之
,
Java
的设计者认为共享带来的高效率远远胜过于提取
、
拼接字符串所带来的
低效率
。
查看一下程序会发现
:
很少需要修改字符串
,
而是往往需要对字符串进行比较
(
有
一种例外情况
,
将来自于文件或键盘的单个字符或较短的字符串汇集成字符串
。
为此
,
Java
提供了一个独立的类
,
在
3.6
.
9
节中将详细介绍
)
。
字符串是否相等
可以使用
equals
方法检测两个字符串是否相等
。对于表达式
s
.
equal
s
(
t)
如果字符串
s
与字符串
t
相等
,
则返回
true
;
否则
,
返回
false
。
一定不要使用
=
运算符检测两个字符串是否相等
!
这个运算符只能够确定两个字串
是否放置在同一个位置上
。
当然
,
如果字符串放置在同一个位置上
,
它们必然相等
。
但是
,
完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上
。
String
greeting
=
"
Hello
"
;
/
/
initialize
greeting
to
a
string
if
(
greeting
=
=
"
Hello
"
)
.
//
probably
true
if
(
greeting
.
substring
(
0
,
3
)
==
"
HeV
)
.
.
.
/
/
probably
false
如果虚拟机始终将相同的字符串共享
,
就可以使用
=
运算符检测是否相等
。
千万不要使用=
=
运算符测试字符串的相等性
,
以免在程序中出现糟糕的
bug
。
空 串 与
Null
串
空串
"
"
是长度为
0
的字符串
。
可以调用以下代码检查一个字符串是否为空
:
if
(
str
.
lengthQ
=
0
)
或
if
(
str
.
equals
(
""
)
)
空串是一个
Java
对象
,
有自己的串长度
(
0
)
和内容
(
空
)
。
不过
,
String
变量还可以存
放一个特殊的值
,
名为
null
,
这表示目前没有任何对象与该变量关联
(
关于
null
的更多信息
请参见第
4
章
)
。
要检查一个字符串是否为
null
,
要使用以下条件
:
if
(
str
=
=
null
)
有时要检查一个字符串既不是
null
也不为空串
,
这种情况下就需要使用以下条件
:
if
(
str
!
=
null
&
&
str
.
lengthO
!
=
0
)
首先要检查
str
不为
null
。
构 建 字 符 串
有些时候
,
需要由较短的字符串构建字符串
,
例如
,
按键或来自文件中的单词
。
采用字
符串连接的方式达到此目的效率比较低
。
每次连接字符串
,
都会构建一个新的
String
对象
,
既耗时
,
又浪费空间
。
使用
StringBuildei
•
类就可以避免这个问题的发生
。
如果需要用许多小段的字符串构建一个字符串
,
那么应该按照下列步骤进行
。
首先
,
构
建一个空的字符串构建器
:
StringBuilder builder = new StringBuilder();
当每次需要添加一部分内容时
,
就调用
append
方法
。
builder.append(ch); // appends a single character
bui1der.append(str); // appends a string
在需要构建字符串时就凋用
toString
方法
,
将可以得到一个
String
对象
,
其中包含了构建器
中的字符序列
。
String completedString = builder.toString();