一、创建字符串
// 方式一
String str = "Hello";
// 方式二
String str2 = new String("Hello");
// 方式三
char[] array = {'a', 'b', 'c'};
String str3 = new String(array);
String str1 = "Hello";
String str2 = str1;
的代码内存布局如下:

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2);
// 执行结果
false
为什么结果会是false呢?这是因为 String 使用 == 比较并不是在比较字符串内容, 而是比较两个引用是否指向同一个对象(身份)。而此时的代码内存布局也变了:
那么在Java中,如何比较两个字符串的内容是否相等呢?这就要引入 String 类中的 .equals 方法了。即:
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2)); //或System.out.println(str2.equals(str1));
// 执行结果
true
※小贴士:在比较一个字符串和一个字符串常量是否相等时,一旦这个一个字符串是 null,代码就会抛出异常,因此我们可以写作:System.out.println("Hello".equals(str));这种形式。
二、字符串常量池
※另外我们可以使用 String 的 intern 方法来手动把 String 对象加入到字符串常量池中:
String str1 = new String("hello").intern() ;
String str2 = "hello" ;
System.out.println(str1 == str2);
// 执行结果
true
三、字符串不可变
字符串是一种不可变对象,它的内容不可改变。String 类的内部实现也是基于 char[] 来实现的, 但是 String 类并没有提供 set 方法之类的来修改内部的字符数组。那么如果实在需要修改字符串该怎么办?
String str = "Hello";
str = "h" + str.substring(1);
System.out.println(str);
// 执行结果
hello
2)使用 "反射" 这样的操作可以破坏封装,访问一个类内部的 private 成员。
四、字符与字符串
方法 | 描述 | |
1 | public String (char value[]) | 将字符数组中的所有内容变为字符串 |
2 | public String(char value[],int offset,int count) | 将部分字符数组中的内容变为字符串 |
3 | public char charAt(int index) | 取得指定索引位置的字符(索引从0开始) |
4 | public char[] toCharArray() | 将字符串变为字符数组返回(创建了新的数组) |
五、字节与字符串
方法 | 描述 | |
1 | public String (byte bytes[]) | 将字节数组变为字符串 |
2 | public String(byte bytes[],int offset,int length) | 将部分字节数组中的内容变为字符串 |
3 | public byte[] getBytes() | 将字符串以字节数组的形式返回 |
六、字符串常见操作
方法 | 描述 | |
1 | public boolean equals(Object anObject) | 区分大小写的比较 |
2 | public boolean equalsIgnoreCase(String anotherString) | 不区分大小写的比较 |
3 | public int compareTo(String anotherString) | 比较两个字符串大小关系(根据“字典序”比较,相等返回0,小于返回内容小于0,大于返回内容大于0。) |
方法 | 描述 | |
1 | public boolean contains(CharSequence s) | 判断一个子字符串是否存在 |
2 | public int indexOf(String str) | 从头开始查找指定字符串的位置,查到了返回位置的开始索引,如果查不到返回-1 |
3 | public int indexOf(String str,int fromIndex) | 从指定位置开始查找子字符串位置 |
4 | public int lastIndexOf(String str) | 由后向前查找子字符串位置 |
5 | public int lastIndexOf(String str,int fromIndex) | 从指定位置由后向前查找 |
6 | public boolean startsWith(String prefix) | 判断是否以指定字符串开头 |
7 | public boolean startsWith(String prefix,int toffset) | 从指定位置开时判断是否以指定字符串开头 |
8 | public boolean endsWith(String suffix) | 判断是否以指定字符串结尾 |
3)字符串替换:由于字符串是不可变对象,替换不修改当前字符串,而是产生一个新的字符串。
方法 | 描述 | |
1 | | 替换所有的指定内容 |
2 | | 替换首个内容 |
4)字符串拆分:主要能用来拆分IP地址。另外有些特殊字符作为分割符可能无法正确切分,需要加上转义。字符"|","*","+"前面都得加上"\";而如果是"",那么就得写成"\\"。
方法 | 描述 | |
1 | | 将字符串全部拆分 |
2 | | 将字符串部分拆分,该数组长度就是limit极限 |
5)字符串截取:区间都是前闭后开。
方法 | 描述 | |
1 | | 从指定索引截取到结尾 |
2 | | 截取部分内容 |
6)其他方法:
方法 | 描述 | |
1 | | 去掉字符串中的左右空格,保留中间空格 |
2 | | 字符串转大写 |
3 | | 字符串转小写 |
4 | | 字符串入池操作 |
5 | | 字符串连接,等同于“+”,不入池 |
6 | | 取得字符串长度 |
7 | | 判断是否为空字符串,但不是 null ,而是长度为 0 |
七、StringBuffer 和 StringBuilder
方法 | 描述 | |
1 |
public synchronized
StringBuffer
append
(
各种数据类型 a
)
| 字符串连接 |
2 |
public synchronized
StringBuffer
reverse
()
| 字符串反转 |
3 |
public synchronized
StringBuffer
delete
(
int
start
,
int
end
)
| 删除指定范围的数据 |
4 |
public synchronized
StringBuffer
insert
(
int
offset
,
各种数据类型 a
)
| 插入数据 |
注:String 和 StringBuffer 类不能直接转换,想互相转换可以采用:String 变为 StringBuffer:利用StringBuffer的构造方法或append()方法;StringBuffer 变为 String:调用toString()方法。
• 由于 StringBuilder类 自身并没有重写 Object类 中的 equals方法,调用就相当于执行了" == "操作,可以用 toString方法 先转成 String类 再用 equals方法 比较其内容即可。
※String、StringBuffer、StringBuilder的区别: