1 String字符串类:所有字符串字面值(如"abc")都是String类的实例实现
字符串是常量,一旦被创建就不能被改变!
字符串缓冲区支持可变的字符串,因为String对象是不可变的,所以可以共享
1.1 直接赋值与new的比较
使用双引号直接赋值时,系统检测该字符串在串池(StringTable)里是否存在(串池在堆内存中),不存在则创建新的,存在则复用
String s1 = "abc"; //串池中没有"abc",则会在内开辟一个空间存储"abc"(0x0011)
String s2 = "abc"; //串池中已经有"abc"(0x0011)
String s3 = new String("abc"); //只要有new,就会在堆内存中开辟空间(0x0022)
String s4 = new String("abc"); //只要有new,就会在堆内存中开辟空间(0x0033)
Scanner sc = new Scanner(System.in);
String s5 = sc.next(); //键盘录入相当于new出来的,会在堆内存中开辟空间(0x0044)
综上所述:
使用String s1 = "abc"直接赋值比String s3 = new String("abc")节省空间
1.2 根据索引返回对应字符
注意获得字符串长度是方法需要加括号:str.length()
数组获取长度是属性,不用加括号:arr.length
String str="abckscho";
for(int i=0;i<str.length();i++){
char c=str.charAt(i);
System.out.print(c);
}
1.3 利用ASCII码表让字符返回为数字
String id="411303200401100344";
char gender=id.charAt(16);
int num=gender-48; //字符在参与运算时自动转换为ASCII码表所对应的数字
注意:char类型的变量在参与计算时类型自动提升为int,查询ASCII码表
public static void count(String str){
int smallCount=0;
int bigCount=0;
int numberCount=0;
for (int i = 0; i < str.length(); i++) {
char c=str.charAt(i);
if (c>='a'&&c<='z'){ //实际上是c字符对应的ASCII码值与a对应的ASCII码值相比较
smallCount++;
}else if (c>='A'&&c<='Z'){
bigCount++;
}else if (c>='0'&&c<='9'){ //实际上是c字符对应的ASCII码值与0对应的ASCII码值相比较
numberCount++;
}
}
1.4 字符翻转
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.print("请输入一个字符串:");
String str=sc.next();
System.out.print(fanZhuan(str));
}
public static String fanZhuan(String str){
String result=""; //字符拼接
for (int i = str.length()-1; i >=0; i--) {
char c=str.charAt(i); //使用charAt()获取每个位置上的字符
result+=c;
}
return result;
}
1.5 截取字符串
substring(int beginIndex,int endIndex); //截取[beginIndex,endIndex)
substring(int beginIndex); //截取到末尾
1.6 字符替换str.replace("旧字符串","新字符串")
//获取说的话
String str="你玩的真好,下次不要再玩了,TMD";
//把TMD替换为***
String result=str.replace("TMD","***");
System.out.println(result);
//定义敏感词汇
String[] arr={"TMD","CNM","SB","MLGB"};
for (int i = 0; i < arr.length; i++) {
str=str.replace(arr[i],"***");
}
System.out.println(str);
1.7 字符串转换为字符数组toCharArray(),字符数组转换为字符串
String str = "abcd";
char[] arr = str.toCharArray(); //arr[] = ['a','b','c','d']
String str2 = new String(arr) //str2 = "abcd"
2 StringBuilder:一个容器,创建之后里面的内容可变
(1)构造方法
public SrtingBuilder( ),创建一个空白可变字符串对象,不含有任何内容
public SrtingBuilder( String str ),根据字符串内容创建可变字符串对象
(2)常用方法
sb.append(任意类型),添加数据,返回对象本身
sb.reverse( ),反转容器中的内容
sb.length( ),返回长度
sb.toString( ),把StringBuilder转换为String返回
//创建对象
StringBuilder sb=new StringBuilder("123");
//添加元素
sb.append(124).append(true).append("abc"); //链式编程
//打印
System.out.println(sb);
//反转
sb.reverse();
System.out.println(sb);
//获取长度
System.out.println(sb.length());
//把StringBuilder变回字符串
String str=sb.toString();
System.out.println(str);
//判断字符串是否对称
Scanner sc=new Scanner(System.in);
System.out.print("请输入一个字符串:");
String str1=sc.next();
String str2=new StringBuilder().append(str1).reverse().toString();
if (str1.equals(str2)){
System.out.println("对称");
}else{
System.out.println("不对称");
}
3 StringJoiner
(1)构造方法
public StringJoiner(间隔符号)
public StringJoiner(间隔符号,开始符号,结束符号)
(2)常用方法
sj.add(添加的内容),添加数据返回对象本身
sj.length( ),返回长度
sj.toString( ),把StringJoiner转换为String返回
//按指定格式拼接字符串
//方法一:使用StringBuilder
public static void main(String[] args) {
int[] arr={1,2,3};
show(arr);
}
public static void show(int[] arr){
StringBuilder str1=new StringBuilder().append("[");
for (int i = 0; i < arr.length-1; i++) {
str1.append(arr[i]).append(",");
}
String str2=str1.append(arr[arr.length-1]).append("]").toString();
System.out.println(str2);
}
//方法二:使用StringJoiner
int[] arr={1,2,3};
StringJoiner sj=new StringJoiner(",","[","]");
for (int i = 0; i < arr.length; i++) {
sj.add(arr[i]+"");
}
System.out.println(sj);
4 字符串相关类的底层原理
(1)字符串存储的内存原理
直接赋值复用字符串常量池中已有的字符串
new出来不会复用,而是开辟一个新的空间
(2)==号比较的内容
基本数据类型比较数据值
引用数据类型比较地址值,使用equals方法比较内容
(3)字符串拼接的底层原理
拼接时没有变量,会触发字符串优化机制,在编译时已是最终结果"abc"
String s1 = "a" + "b" +"c"; //java文件,记录在串池中的地址值
String s2 = "abc"; //class文件,复用串池中的字符串
System.out.println(s1 == s2); //true
拼接时有变量,JDK8以前系统自动创建一个StringBuilder对象,然后调用append()完成拼接,拼接后调用toString()转换为String类型,而toString()底层原理是直接new了一个字符串对象。即:String s2 = s1 + "b"使用new StringBuilder()创建对象s2,s2.append("b").toString()使s2 = "ab",s3同理。
JDK8后,系统预估字符串拼接后的大小,把要拼接的内容都放在数组中,此后产生一个新的字符串
String s1 = "a"; //记录在串池中的地址值给s1
String s2 = s1 + "b"; //新new出来的对象
String s3 = s2 + "c";
(4)StringBuilder自动扩容分析
-
默认创建一个长度为16的字节数组
-
添加的内容<16,直接存
-
添加的内容>16,扩容(原容量*2+2)
-
扩容后还不够,则以实际长度为准
(5)StringBuilder提高效率原理分析
所有要拼接的内容都会放在StringBuilder中,不会创建很多无用的空间,节约内存