一.字符串的存储
* 1.字符串缓冲区
-
字符串是常量, 不能被修改, 所以可以共享, 多个引用指向相同的字符串常量时, 其实引用的是同一个对象, 这个对象在缓冲区中
示例1:
-
String s1 = "abc";
-
String s2 = "abc";
-
System.out.println(s1 == s2);
-
结果为: true
-
原理是: 使用双引号形式的字符串常量时, 会先在缓冲区内查找, 如果没有就创建, 如果有就直接引用.
-
这段代码总共创建了几个字符串对象: 第一句创建了一个, 第二句没有创建.
示例2:
-
String s1 = "abc";
-
String s2 = new String("abc");
-
System.out.println(s1 == s2);
-
结果为: false
-
原理是: 双引号常量是在缓冲区中, 构造函数创建的字符串不在缓冲区中.
-
这段代码总共创建了几个字符串对象: 第一句创建一个对象, 第二句创建一个对象.
* 2.字符串串联
示例1:
-
String s1 = "abc";
-
String s2 = "a";
-
String s3 = "bc";
-
String s4 = s2 + s3;
-
System.out.println(s1 == s4);
-
结果为: false
-
原理是: 字符串相加是通过StringBuffer类的append()和toString()实现的, 而toString()返回的字符串是通过构造函数创建的.
示例2:
-
String s1 = "abc";
-
String s2 = "a" + "bc";
-
结果为: true
-
原理是: 两个字符串常量相加, 在编译的时候之间改为一个字符串常量.
3.字符串类构造函数
-
使用平台默认码表, 将字节数组转为字符串:String(byte[] bytes)
-
使用指定码表, 将字节数组转为字符串:String(byte[] bytes, String charsetName)
-
使用指定码表, 将字节数组中的一部分数据转为字符串:String(byte[] bytes, int offset, int length, String charsetName)
-
使用字符数组创建字符串:String(char[] value)
*** 4.字符串常用方法
-
查找指定位置上的字符: char charAt(int index)
-
查找指定字符第一次出现的位置:int indexOf(String str)
-
查找指定字符最后一次出现的位置: int lastIndexOf(String str)
-
替换字符串:String replace(CharSequence target, CharSequence replacement)
-
截取字符串的子串:String substring(int beginIndex, int endIndex)
-
分割字符串:String[] split(String regex)
-
判断是否包含一个字符串:boolean contains(CharSequence s)
-
按字典顺序比较两个字符串:int compareTo(String anotherString)
-
获取长度:int length()
-
去掉前后空白:String trim()
5.StringBuffer和StringBuilder的区别
-
StringBuffer是从JDK1.0就有的一个类, 可以对字符串进行追加, 插入, 反转等操作, 线程安全同步的, 但是效率较低. 我们在单线程访问的时候不需要同步.
-
在JDK5之后, 出现了StringBuilder类, 它的功能和StringBuffer相同, 但是没有进行同步, 速度快, 淘汰了StringBuffer.
6.写出下面代码的运行结果
-
public class Foo {
-
public static void main(String[] args) {
-
String strValue = "ABCDEFG";
-
strValue.substring(3);// String类所有方法都不会改变原字符串的值
-
strValue.concat("123");
-
System.out.println(strValue);
-
String value = new String ("ABCDEFG");// ABCDEFG
-
System.out.println(strValue == value);// false
-
}
-
}