CSDN话题挑战赛第2期
参赛话题:学习笔记
字符串常量池
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
String s4 = new String("hello");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s3 == s4); // false
}
结果:
上述程序创建方式类似,为什么s1和s2引用的是同一个对象,而s3和s4不是呢?
图解:
Java中的创建的String类
的内容是在字符串常量池中,字符串常池是在堆区中
在常量池中由“ ”
引起来的字符串如果相同,只会存储一份,不会重复的存储,节省了空间
在Java中,比如:1、3.14、“abc” 等等这些字名类型常量会经常频繁的使用到
为了使程序的运行速度更快、更节省内存
,Java为8种基本数据类型和String类都提供了常量池
池
是程序中用来提升效率的方式,未来还会在学习中遇到各种 “内存池”, “线程池”, “数据库连接池”
intern 方法
intern 方法的作用:该方法的作用是手动将创建的String对象添加到常量池中
intern 是一个native方法,Native方法指:底层使用C++实现的,看不到其实现的源代码
例如:
public static void main(String[] args) {
char[] ch = new char[]{'a', 'b', 'c'};
String s1 = new String(ch);
//s1.intern();
String s2 = "abc";
System.out.println(s1 == s2);
}
图解:
字符串的不可变性
String是一种不可变对象. 字符串中的内容是不可改变和不可被修改
String类在设计时就是不可改变的,String类实现描述中已经说明了
String类
中的字符实际保存在value
字符数组中
String类
被 final
所修饰,表示它不能被继承
value
被 final
修饰,表示即不能引用其它字符数组,但是其引用空间中的内容可以修改
真正不能改变的原因 value
数组是有 private
所修饰的
字符串的修改StringBuilder
由于String的不可更改特性,为了方便字符串的修改,Java中又提供String Builder
和String Buffer
类
这两个类大部分功能都是相同的
String Builder
里的方法介绍:
方法 | 作用 |
---|---|
StringBuff append (String str) | 在字符串的尾部追加变量(boolean、char、char[]、double、float、int、long、Object、String、StringBuff) |
char charAt (int index) | 获取 index 位置的字符 |
int length() | 获取字符串的长度 |
int capacity() | 获取底层保存字符串空间总的大小 |
indexOf (String str) | 返回 str 第一次出现的位置 |
indexOf (String str, int fromIndex) | 从fromIndex位置开始查找str第一次出现的位置 |
int lastIndexOf (String str) | 返回最后一次出现str的位置 |
int lastIndexOf (String str,int fromIndex) | 从fromIndex位置开始找str最后一次出现的位置 |
StringBuffinsert (intoffset, String str) | 在offset位置插入:八种基类类型 & String类型 & Object类型数据 |
StringBufferdeleteCharAt(int index) | 删除index位置字符 |
StringBuffer delete(int start, int end) | 删除[start, end)区间内的字符 |
StringBuffer replace(int start, int end, String str) | 将[start, end)位置的字符替换为str |
String substring(int start) | 从start开始一直到末尾的字符以String的方式返回 |
String substring(int start,int end) | 将[start, end)范围内的字符以String的方式返回 |
StringBuffer reverse() | 反转字符串 |
String toString() | 将所有字符按照String的方式返回 |
以上方法使用示范:
append示范:
在字符串的尾部追加变量
public static void main(String[] args) {
StringBuilder n = new StringBuilder("hello");
System.out.println(n);//输出 n 变量的字符串
n.append(" world");// 在 n 字符串的尾部加上 字符串
System.out.println(n);
n.append(123);
System.out.println(n);
}
结果:
charAt 示范:
charAT
获取()
里下标的字符
public static void main(String[] args) {
StringBuilder n = new StringBuilder("hello");
char a = n.charAt(0); // 把下标为 0 的字符赋值给 ch
System.out.println(n.charAt(0));//打印下标 0 的字符
for (int i = 0; i < n.length(); i++) {
System.out.println(n.charAt(i));//循环打印下标 i 的字符
}
}
结果:
capacity( ) 示范:
获取底层保存字符串空间总的大小
public static void main(String[] args) {
StringBuilder n = new StringBuilder("hello");
System.out.println(n.capacity());
}
reverse( ) 示范:
把字符串逆转
public static void main(String[] args) {
StringBuilder arr = new StringBuilder("hello");
arr.reverse();
System.out.println(arr);
}
结果:
String 和 StringBuilder 的区别
String
和StringBuilder
最大的区别在于String
的内容无法修改,而StringBuilder
的内容可以修改
频繁修改字符串的情况考虑使用StringBuilder
String和StringBuilder类不能直接转换
如果要想互相转换,可以采用如下原则:
String
变为StringBuilder
: 利用StringBuilder
的构造方法或append()
方法
例如:
public static void main(String[] args) {
String n = "hello";
StringBuilder arr = new StringBuilder(n);
System.out.println(arr);
}
StringBuilder
变为String
: 调用toString()
方法
例如:
public static void main(String[] args) {
StringBuilder n = new StringBuilder("hello");
String str = n.toString();
System.out.println(str);
}
总结:
String、StringBuffer、StringBuilder的区别
String
的内容不可修改,StringBuffer
与StringBuilder
的内容可以修改StringBuffer
与StringBuilder
大部分功能是相似的,StringBuffer
大多使用在多线程,StringBuilder
是单线程