String
String基础
-
String类又称作不可变字符序列。
-
String位于java.lang包中,Java程序默认导入java.lang包下的所有类。
-
Java字符串就是Unicode字符序列,例如字符串“Java”就是4个Unicode字符’J’、’a’、’v’、’a’组成的。
-
Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义的类String,每个用双引号括起来的字符串都是String类的一个实例。
String类和常量池
在Java的内存分析中,我们会经常听到关于“常量池”的描述,实际上常量池也分了以下三种:
1. 全局字符串常量池(String Pool)
全局字符串常量池中存放的内容是在类加载完成后存到String Pool中的,在每个VM中只有一份,存放的是字符串常量的引用值(在堆中生成字符串对象实例)。
2. class文件常量池(Class Constant Pool)
class常量池是在编译的时候每个class都有的,在编译阶段,存放的是常量(文本字符串、final常量等)和符号引用。
3. 运行时常量池(Runtime Constant Pool)
运行时常量池是在类加载完成之后,将每个class常量池中的符号引用值转存到运行时常量池中,也就是说,每个class都有一个运行时常量池,类在解析之后,将符号引用替换成直接引用,与全局常量池中的引用值保持一致。
String类常用的方法
[外链图片转存失败(img-xM0ssWHu-1563260953228)(https://www.sxt.cn/360shop/Public/admin/UEditor/20170522/1495417924711064.png)]
字符串相等的判断
-
equals方法用来检测两个字符串内容是否相等。如果字符串s和t内容相等,则s.equals(t)返回true,否则返回false。
-
要测试两个字符串除了大小写区别外是否是相等的,需要使用equalsIgnoreCase方法。
-
判断字符串是否相等不要使用"=="。
忽略大小写的字符串比较
`"Hello"``.equalsIgnoreCase(``"hellO"``);``//true`
不可变的字符序列
String 类对象代表不可变的Unicode字符序列,因此我们可以将String对象称为“不可变对象”。 那什么叫做“不可变对象”呢?指的是对象内部的成员变量的值无法再改变。我们打开String类的源码。
/** The value is used for character storage. */
private final char value[];
可变的字符序列
StringBuffer和StringBuilder非常类似,均代表可变的字符序列。 这两个类都是抽象类AbstractStringBuilder的子类,方法几乎一模一样。我们打开AbstractStringBuilder的源码。
/**
* The value is used for character storage.
*/
char value[];
显然,内部也是一个字符数组,但这个字符数组没有用final修饰,随时可以修改。因此,StringBuilder和StringBuffer称之为“可变字符序列”。那两者有什么区别呢?
-
StringBuffer JDK1.0版本提供的类,线程安全,做线程同步检查, 效率较低。
-
StringBuilder JDK1.5版本提供的类,线程不安全,不做线程同步检查,因此效率较高。 建议采用该类。
常用方法列表:
- 重载的public StringBuilder append(…)方法
可以为该StringBuilder 对象添加字符序列,仍然返回自身对象。
- 方法 public StringBuilder delete(int start,int end)
可以删除从start开始到end-1为止的一段字符序列,仍然返回自身对象。
- 方法 public StringBuilder deleteCharAt(int index)
移除此序列指定位置上的 char,仍然返回自身对象。
- 重载的public StringBuilder insert(…)方法
可以为该StringBuilder 对象在指定位置插入字符序列,仍然返回自身对象。
- 方法 public StringBuilder reverse()
用于将字符序列逆序,仍然返回自身对象。
- 方法 public String toString() 返回此序列中数据的字符串表示形式。
不可变和可变字符序列使用陷阱
String使用的陷阱
String一经初始化后,就不会再改变其内容了。对String字符串的操作实际上是对其副本(原始拷贝)的操作,原来的字符串一点都没有改变。比如:
String s =“a”; 创建了一个字符串
s = s+“b”; 实际上原来的"a"字符串对象已经丢弃了,现在又产生了另一个字符串s+“b”(也就是"ab")。 如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的时间和空间性能,甚至会造成服务器的崩溃。
相反,StringBuilder和StringBuffer类是对原字符串本身操作的,可以对字符串进行修改而不产生副本拷贝或者产生少量的副本。因此可以在循环中使用。
要点:
-
String:不可变字符序列。
-
StringBuffer:可变字符序列,并且线程安全,但是效率低。
以对字符串进行修改而不产生副本拷贝或者产生少量的副本。因此可以在循环中使用。
要点:
-
String:不可变字符序列。
-
StringBuffer:可变字符序列,并且线程安全,但是效率低。
-
StringBuilder:可变字符序列,线程不安全,但是效率高(一般用它)。