概述
String类表示字符串。 Java程序中的所有字符串文字(例如“abc”)都实现为此类的实例。
字符串是不变的; 它们的值在创建后无法更改。
字符串缓冲区支持可变字符串。
String内存相关
字符串常量存在于方法区,方法区,又称永久代(只要程序不关闭,就永远储存在内存中),又称非堆区
方法区是被所有线程共享的
堆 在逻辑上分为三部分:
新生代:指的是刚创建的内存所存储的位置。因为这个部分的GC询问次数进行得特别快。
老年代:当新生代经过15次新生代GC询问后还没有被回收的内存就被存入老年代,他的GC询问次数就会比较少。
永久代:永远不GC回收。
因为String对象是不可变的,如果存在多个内容相同的字符串,则采用同一块内存地址储存它们
例:
public class Demo1 {
public static void main(String[] args) {
String text = "123";
String text2 = "123";
System.out.println(text == text2);
}
}
输出
true
就算是不同的对象text和text2,但是他们字符串内容相同,那么地址就相同。这是String的特性。
原理:程序开始,创建了一个字符串常量"123",并存入永久代,下面创建另一个字符串对象后,搜索永久代区域,如果发现内容是一样的,那么直接复制它的内存地址过来。所以两个不同对象,内容相同,内存地址相同。
但是,如果创建字符串对象时,通过new关键字创建,那么一定是新开辟的空间
例
public class Demo1 {
public static void main(String[] args) {
String text = "123";
String text2 = new String("123");
System.out.println(text == text2);
}
}
输出
false
text2新开辟了空间,内存地址不同,返回false
如果需要进行字符串拼接,因为内存问题我们应该尽量避免使用“+”拼接,转而使用其他的两个类:StringBuffer和StringBuilder用来解决字符串拼接,对于我们目前的学习进度来说,使用他们两者谁都OK,都可以拼接字符串,并节省内存,他们的操作方式完全相同。但还是区别一下,StringBuilder是线程不安全的实现,StringBuffer是线程安全的实现。
使用StringBuffer和StringBuilder拼接字符串常用的两个方法:
append方法:向对象中添加字符串(也就是拼接)
toString方法:将对象转为一个String类型的字符串
例
public class Demo1 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("123");
sb.append(1);
System.out.println(sb.toString());
}
}
输出
1231
String类常用方法
trim方法
作用:删除传入字符串的所有前导和尾随空格,更准确的说,trim删除的是字符串前端和尾部unicode码小于33的字符,(空格的unicode码是32)。一般用于登录时的输入验证。
例:
public class Demo5 {
public static void main(String[] args) {
String s = " \ta bc ";
s = s.trim();
System.out.println(s);
}
}
输出
a bc
我们可以看到,trim方法不仅删除了两端空格,连制表符 \t 都被删了,那是因为 \t 的Unicode码是9
charAt方法
作用:返回指定索引处的char值,可以获取字符串中任意下标的char型数据。
例
public class Demo5 {
public static void main(String[] args) {
String s = "abcde";
char a = s.charAt(1);
System.out.println(a);
}
}
输出
b
split方法
作用:用于按传入的字符或字符串对String进行拆分,返回拆分之后的数组。
例:
用法一:单个字符分割
String s = "a哈哈b哈哈c哈哈d哈哈e";
String[] str = s.split("哈哈");
输出str:
[a,b,c,d,e]
用法二:多字符分割,用 | 隔开
String s = "a b$c@d#e";
String[] str = s.split(" |#|@|$");
输出str
[a,b,c,d,e]
用法三:需要转义的分割符
当使用* ^ : | . \等6个符号做分隔符时,前面要加上\\
String s = "a*b c d e";
String[] str = s.split("\\*| ");
输出str
[a,b,c,d,e]
StringBuffer/StringBuilder类类常用方法
append方法
作用:将字符串拼接到StringBuffer对象的字符串缓冲区
例
public class Demo5 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append(123);
sb.append("abc");
System.out.println(sb.toString());
}
}
输出
123abc
toString方法
作用:将StringBuffer/StringBuilder对象转为String类型的字符串并返回。
reverse方法
作用:返回一个翻转字符串
例
public class Demo5 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("Hello World");
sb.reverse();
System.out.println(sb.toString());
}
}
输出
dlroW olleH
关于String类的一些练习题记录
1.编写一个方法,将一段文本中的各个单词的字母顺序翻转
例如:"I like writing code best",将变成"I ekil gnitirw edoc tseb"。
解:本题主要运用String类的split方法,获取单词,然后将每个单词依次存入字符串数组,再利用StringBuffer类的reverse方法,将每个单词进行顺序翻转
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String s = input.nextLine();//接收用户输入的一行字符串,可以包含空格,以回车结束
change(s);
}
/**
* 传入一个字符串,利用String类的split方法将每个单词存入一个字符数组
* 然后利用循环将每个单词都送入Suffer中,进行反转
* 反转后的字符串,覆盖原数组,最后输出数组
* @param s 用户输入的一个英文句子,以空格将每个单词分隔
* @return
*/
public static void change(String s) {
String[] str = s.split(" "); //调用split方法,将字符串中的空格删除,并将空格两端的字符串依次存入数组
for(int i =0;i<str.length;i++){ //遍历单词数组
StringBuffer sb = new StringBuffer(); //创建StringBuffer对象 sb
sb.append(str[i]); //将单词压入sb内
sb.reverse(); //将sb内的字符串翻转
str[i] = sb.toString(); //翻转后的字符串又赋给数组
if(i == str.length-1){
System.out.print(str[i]);
}
else{
System.out.print(str[i]+' ');
}
}
}
}
输入:I like writing code best
输出:I ekil gnitirw edoc tseb