String 类
自从学了String类,麻麻再也不用担心我的字符串操作了。用起来相对还是比较爽的,不学白不学,学了不白学!
-
字符串是常量,创建之后不可改变。
//修改字符串的内容 String str = "hello"; str = str + " world";
内存分配图:
-
字符串字面值存储在字符串池中,可以共享。
- 在Java中形成一个对象池,在这个对象池中保存多个对象,新实例化的对象如果已经在池中定义了,则不再重新定义,而从池中直接取出继续使用。
- String就是采用这样的设计,所以当内容重复时,会将对象指向已存在的实例空间。
实例化String对象
-
直接为String赋值
String name = "xiaoming";
-
使用标准的new调用构造方法完成实例化
String name = new String("xiaoming");
两种实例化方式的区别
首先了解一个概念:一个字符串就是一个String类的匿名对象。匿名对象就是已经开辟了堆内存空间的并可以直接使用的对象。
简单来说,字符串可以直接调用String类中的方法,就是一个匿名对象。
//字符串能够调用String类中的方法
"xiaoming".equals("xiaoming");
"xiaoming".charAt(0);
1.直接赋值
String name = "xiaoming";
实际上是把一个在堆中开辟好的对内存空间的使用权给了name对象,而使用这种方式有另一个好处,就是如果一个字符串已经被另一个名称所引用,以后再有相同的字符串声明时,就不会再重新开辟空间,而继续使用已经开辟好的堆内存。
实例:
public class Main{
public static void main(String[] args){
String str1 = "hello";
String str2 = "hello";
String str3 = "hello";
System.out.println(str1 == str2);
System.out.println(str2 == str3);
System.out.println(str1 == str3);
}
}
运行结果:
从结果可以发现,所有字符串都使用了"=="进行比较,所得到的结果都为true
,也就是说这3个字符串指向的堆内存地址空间都是同一个,所以,当String使用直接赋值方式之后,只要字符串内容相同,都不会再开辟新的内存空间,如图所示。
2.使用new String()的方式实例化对象
String str = new String("hello");
一个字符串就是一个String类的匿名对象,而如果使用new关键字,不管如何都会再开辟一个新空间,此时空间的内容还是hello,所以上面的代码实际上是开辟了两个内存空间,但真正使用的只是一个使用关键字开辟的空间,另外一个就是垃圾空间了,如图所示。
常用方法
方法 | 描述 |
---|---|
toCharArray() | 将一个字符串变为字符数组 |
charAt(int index) | 从一个字符串中取出指定位置的字符 |
length() | 取得字符串的长度 |
indexOf(String str) | 从头开始查找指定的字符串首次出现的位置,找不到返回-1 |
indexOf(String str,int fromIndex) | 从指定位置开始查找指定的字符串首次出现的位置 |
trim() | 清除左右两端的空格 |
substring(int beginIndex ) | 从指定位置开始,一直取到尾进行字符串的截取 |
substring(int begin,int end) | 指定截取字符串的开始点和结束点 |
split(String regex) | 按照指定的字符串进行拆分,返回一个字符串数组。(支持正则表达式) |
toUpperCase() | 将一个字符串全部变为大写字母 |
toLowerCase() | 将一个字符串全部变为小写字母 |
contains(CharSequence s) | 判断字符串是否包含某个字符或字符串 |
startsWith(String prefix) | 判断是否以指定的字符串开头 |
endsWith(String suffix) | 判断是否以指定的字符串结尾 |
equals(String str) | 判断两个字符串内容是否相等 |
equalsIgnoreCase(String str) | 不区分大小写比较两个字符串是否相等 |
replaceAll(String regex,String replacement) | 字符串替换(支持正则表达式) |
实例
public class Main {
public static void main(String[] args) {
String str1 = "Hello world";
String str2 = " HELLO WoRLD ";
System.out.print("字符数组:");
char[] alone = str1.toCharArray();//将字符串变为字符数组
for (int i = 0; i < alone.length; i++) {
System.out.print(alone[i] + ",");
}
System.out.println();
System.out.println("第2个字符:" + str1.charAt(1));//取出第二个字符
System.out.println("长度:" + str1.length());//str1的长度
System.out.println("查找字符串wo:" + str1.indexOf("wo"));//查找字符串”wo“首次出现的位置位置从0开始
System.out.println("从指定位置查找字符串o:" + str1.indexOf("o", 5));
System.out.println("清除str2左右两端的空格:" + str2.trim());
System.out.println("从指定位置到末尾截取:" + str1.substring(1));
System.out.println("指定截取开始点和结束点:" + str1.substring(0, 5));//截取字符,包括开始点,不包括结束点
System.out.print("字符串拆分:");
String[] words = str1.split(" ");
for (int i = 0; i < words.length; i++) {
System.out.print(words[i] + ",");
}
System.out.println();
System.out.println("将字符串全部变为大写字母:" + str1.toUpperCase());
System.out.println("将字符串全部变为小写字母:" + str2.toLowerCase());
System.out.println("判断是否以He开头:" + str1.startsWith("He"));
System.out.println("判断是否以空格结尾:" + str1.endsWith(" "));
System.out.println("判断两个字符串是否相等:" + str1.equals(str2));
System.out.println("判断两个字符串是否相等(不区分大小写):" + str1.equalsIgnoreCase(str2.trim()));//这里是先将str2的两端的空格去掉再进行比较
System.out.println("将l替换为c:" + str1.replaceAll("l", "c"));
}
}
运行结果
总结
- 使用String类中的方法能够对字符串相关操作,在一定程度上更方便快捷。
- 存在一定的缺点,如在对一个字符串进行频繁修改时,在效率上极低。
- 为弥补上述缺点,可使用StringBuffer和StringBuilder进行相关操作。
- 所写的String类方法只是部分内容,如果想了解更多,可自行查询API文档。
如有错误,欢迎指正!!!