栈、堆、常量池
概念
- 栈:存取速度比堆要快,仅次于直接位于CPU中的寄存器。缺点在于存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享
- 堆:可以动态地分配内存大小,所有使用new xxx()构造出来的对象都在堆中存储,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢
- 常量池:存放字符串常量和基本类型常量(public static final)。常量池的好处是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享
String s = " "
创建过程:
- 先定义一个名为str的对String类的对象引用变量放入栈中
- 在常量池中查找是否存在内容为"abc"字符串对象
- 如果不存在则在常量池中创建"abc",并让str引用该对象
- 如果存在则直接让str引用该对象
- 相同的值会指向常量池中相同的地方
- 当一个变量的值被创建或发生改变时,首先搜索常量池中是否存在那个值并指向它,否则创建新值
String s = new String(" ")
创建过程:
- 先定义一个名为str的String类的对象引用变量放入栈中
- 然后在堆中(不是常量池)创建一个指定的对象,并让str引用指向该对象
- 在常量池中查找是否存在内容为"abc"字符串对象
- 如果不存在,则在常量池中创建内容为"abc"的字符串对象,并将堆中的对象与之联系起来
- 如果存在,则将new出来的字符串对象与字符串常量池中的对象联系起来(即让那个特殊的成员变量value的指针指向它)
面试题:String s = new String("abc");产生几个对象?答:一个或两个,如果常量池中原来没有"abc",就是两个
其它事项
当比较包装类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==
由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率
String类
String s = " "
由String创建的字符串不能修改,若要修改可以用StringBuffer类
转义字符
在需要转义的字符前添加"\\"
字符串长度
s.length()
连接字符串
s1+s2
格式化字符串
System.out.println("%f, %d, %s", floatVar, intVar, stringVar)
其它常用方法
char charAt()
从字符串中取出指定位置的字符
char c = s.charAt(3)
char toCharArray()
将字符串变成一个字符数组
char c[] = s.toCharArray()
输出['a', 'b', 'c']
string valueOf(object o)
返回对象的字符串表示形式
System.out.println(string.valueOf(o));
int indexOf('ch')或int lastIndexOf('ch')
返回ch出现的第一个位置或最后一个位置,不存在返回-1
String toUpperCase()、 String toLowerCase()
字符串大小写的转换
s.toUpperCase()
String[] split(String regex, int limit)
分割字符串,按regex分割limit份并返回字符串数组
regex可为字符、字符串,也可为正则表达式
String[] str = s.split("-", 2)
replace('ch1', 'ch2')、replaceAll("s1", "s2")、replaceFirst("s1", "s2")与trim()
s.trim() 去掉字符串左右两边的空格
s.replace('ch1', 'ch2') 将s中的字符ch1替换成字符ch2
s.replaceAll("s1", "s2")将s中的子串或正则s1替换为s2
s.replaceFirst("s1", "s2")将s中第一次出现的子串或正则s1替换为s2
boolean startsWith()、endsWith()与contains()
s.startsWith("s1", i) s的前缀是否为s1,i为起始下标,默认为0
s.endsWith("s2") s的后缀是否为s2
s.contains("s3") s是否包含子串s3
字符串比较
int i = s.compareTo(字符串或字符串对象)
比较每一位字符直到不等,返回不等字符的ASCII码差值并不继续比较
若字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值
int i = s.compareToIgnoreCase(字符串或字符串对象)
忽略大小写进行比较
boolean equals(Object anObject)
String 中 == 比较引用地址是否相同,equals() 比较字符串的内容是否相同
e.g.
String s1 = "Hello"; // String 直接创建
String s2 = "Hello"; // String 直接创建
String s3 = s1; // 相同引用
String s4 = new String("Hello"); // String 对象创建
String s5 = new String("Hello"); // String 对象创建
s1 == s1; // true, 相同引用
s1 == s2; // true, s1 和 s2 都在公共池中,引用相同
s1 == s3; // true, s3 与 s1 引用相同
s1 == s4; // false, 不同引用地址
s4 == s5; // false, 堆中不同引用地址
s1.equals(s3); // true, 相同内容
s1.equals(s4); // true, 相同内容
s4.equals(s5); // true, 相同内容