String
概述
java.lang.String
类代表字符串,java程序中的所有字符串文字都是此类的对象。
注:
字符串的内容是不会发生改变的,它的对象在创建后不能被更改。
String是java定义好的类,定义在java.lang包下故使用时不需要导入包
//拼接字符串是产生了一个新的字符串!
String name="wdadwa";
String name2="aaa";
System.out.println(name+name2);
//这个是创建了一个新的字符串bbb再把bbb赋值给了a
String a="aaaaa";
a="bbbbb";
创建String对象的俩种方式
-
直接赋值
String name="wdadwa";
-
new方法
String s1=new String();//空参构造 String s2=new String("字符串");//传递一个字符串,根据传递的内容再创建一个新的字符串对象 //根据字符数组创建字符串 char[] chs={'a','b','c'}; String s3=new String(chs);//一旦new后就无法更改字符串了内容了只能重新赋值了! //这个很重要因为字符串是不能进行修改的,比如不能实现 s3[0]='2'这种情况 //我们就通过修改字符数组来修改字符串 //根据字节数组创建字符串 byte[] b1={91,98,99,100}; String s4=new String(b1);//应用场景:在网络当中传输的数据都是字节信息,此时就要用到它,将字节信息转换为字符串
字符串在内存中如何创建
-
StringTable(字符串常量池)
当我们通过直接赋值的方式赋值字符串的时候,字符串就会存储在StringTable中
在jdk7版本之前这个StringTable是在方法区中的,在之后这个移到了堆内存中。
直接赋值的办法
public class StringDemo{
public static void main(String[] args){
String s1="abc";
String s2="abc";
}
}
- main方法进如栈内存中
- 运行main方法中的代码
- String s1="abc"首先会判断StringTable中是否存在abc这个字符串,因为是第一次创建故不存在abc这个字符串
- 故在StringTable串池中创建abc这个字符串并把地址值赋值给s1
- 然后再执行String s2="abc"此时观察到串池中存在abc这个字符串,故复用这个地址值给s2
总结:
当使用双引号直接赋值的时候,系统会检查该字符串在串池中是否存在
不存在:创建新的
存在:复用
new的方法
public class Test{
public static void main(String[] args){
char[] chs={'a','b','c'};
String s1=new String(chs);
String s2=new String(chs);
}
}
- 先压main方法进栈
- 执行main方法中的代码
char[] chs={'a','b','c'};
此时在堆内存中存储了这个数组,并将这个地址值赋值给了chs变量- 执行
String s1=new String(chs)
此时在堆内存中创建了一个字符串存储的是chs的内容,并将地址值赋值给了s1 - 再次执行
String s2=new String(chs);
此时在堆内存中再次创建了一个字符串存储chs的内容,并将地址值赋值给s2
字符串的比较
-
==号比较的原理
-
比较的是基本数据类型
此时比较的是具体的数据值。
-
比较的是引用数据类型
引用数据类型比较的是地址值。
-
举例
String s1="abc";
String s2="abc";
System.out.println(s1==s2);//true使用直接赋值法地址值存储在串池当中且地址中一致
String s1=new String("abc");
String s2="abc";
System.out.println(s1==s2);//false,此时是俩个地址值
equals方法比较字符串
特点:俩个字符串完全一样才返回true,否则返回false
String s1="abc";
String s2=new String("abc");
System.out.println(s1.equals(s2));//比较s1和s2
equalsIgnoreCase比较字符串
特点:忽略大小写的比较
只能是英文!中文繁体简体是不支持的
String s1="abc";
String s2=new String("abc");
System.out.println(s1.equalsgnoreCase(s2));//忽略大小写比较字符串
键盘录入的Scanner字符串是通过new构造方法来获取的字符串哦~
char变量在进行计算的时候会自动升级为int并查询acsii表
数字字符-48为整数字符哦
String类的几个方法
- 查询
public char charAt(int index);//根据索引返回字符串(下标从0开始)
public int indexOf(String str);//查找对应字符串中索引的位置,如果不存在就返回-1
public int lastIndexOf(String str);//查找对应字符最后在字符串中出现的索引位置,如果没有则返回-1
public int length();//返回字符串的长度
//需要与数组长度区分
//数组是 数组名.length
//因为数组长度是里面的一个属性而字符串的长度是方法
- 修改
public String substring(a,b);//截取字符串,包含a不包含b
public String replace(a,b);//把字符串里面内容a替换成内容b
public String toUpperCase();//将字符串全部转换为大写
public String toLowerCase();//将字符串全部转换为小写
public String trim();//去除字符串头尾的空白
public String concat(String str);//将str字符串内容添加到字符串后面,效果等同=号
举例
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String name=sc.nextLine();
for(int i=0;i<name.length();i++){
System.out.println(name.charAt(i));
}
}
}
StringBuilder
StringBuilder可以看做是一个容器,创建后里面的内容是可变的。
一般用完StringBuilder会将他变回字符串。
-
作用:提高字符串的操作效率。
举例
String s1="aaa";
String s2="bbb";
String s3="ccc";
s1+s2+s3;
//这样产生了aaabbb和aaabbbccc等多余的字符串
//但StringBuilder不会产生多余不需要的字符串
构造方法
public StringBuilder();//创建一个空白可变的字符串对象,里面不含任何内容
public StringBuilder(String str);//根据字符串内容创建可变字符串对象
常用方法
public StringBuilder substring(a,b);//截取字符串,包含a不包含b
public StringBuilder replace(a,b);//把字符串里面内容a替换成内容b
public StringBuilder append(任意类型);//添加数据并返回对象,末尾处哦~
public StringBuilder reverse();//反转容器内容
public int length();//返回长度
public String toString();//通过toString实现将StringBuilder转换为String
public StringBuilder insert(插入位置,插入字符串);
public StringBuilder delete(初始位置,终点位置);
publiuc int capacity();//获取StringBuilder的当前容量
StringBuilder是java已经写好的类,java在底层对其做了一些特殊处理,打印对象不是地址值而是属性值。
链式编程
当我们在调用一个方法的时候,不需要用变量接收它的结构,可以继续调用其他方法。
public class Demo{
public static void main(String[] args){
int len=getString().subString(1).replace("A","Q").length();
//这个方法返回了字符串,不需要用变量接收它而是直接把他当作字符串使用,这个叫链式编程。
}
public static String getString(){
Scanner sc = new Scanner(System.in);
String str=sc.next();
return str;
}
}
public class Demo{
public static void main(String[] args){
StringBuilder sb=new StringBuilder();
sb.append("aaa").append("bbb").append("ccc");//通过链式编程简化写
sb.toString();//因为StringBuilder是一个容器而不是String类型的字符串,故需要变成字符串。
}
}
StringBuffer
- StringBuffer 是一个final类 不能被继承
- StringBuffer是存放在 char[] value ,所有的变化 不用每次创建新对象,更换地址所以效率高于String
- StringBuffer 构造器默认为初始化16个字符
构造方法
public StringBuffer();//空参构造
public StringBuffer(String str);//有参构造
常用方法
public StringBuffer substring(a,b);//截取字符串,包含a不包含b
public StringBuffer replace(a,b);//把字符串里面内容a替换成内容b
public StringBuffer append(任意类型);//添加数据并返回对象,末尾处哦~
public StringBuffer reverse();//反转容器内容
public int length();//返回长度
public String toString();//通过toString实现将StringBuilder转换为String
public StringBuffer insert(插入位置,插入字符串);
public StringBuffer delete(初始位置,终点位置);
StringJoiner
在创建对象的时候可以指定字符串间的结束和开始符号,间隔符号。
StringJoiner和StringBuilder一样,可以看做一个容器,创建之后里面的内容是可变的。
作用:提高字符串操作效率,代码特别简洁。
JDK8之后出现的。
构造方法
public StringJoiner(间隔符号);//用""隔开,创建一个StringJoiner对象,指定拼接时的间隔符号
public StringJoiner(间隔符号,开始符号,结束符号);//创建一个StringJoiner对象,指定拼接时的间隔符号,开始符号,结束符号。
常用方法
public StringJoiner add(添加内容);//添加数据,并返回对象本身,间隔是add之间出现的哦~
public int length();//返回长度
public String toString();//返回一个字符串
public StringJoiner merge(StringJoiner other);//此方法接受一个强制性参数other,该参数是StringJoiner,其内容应合并到此参数中
String字符串一些底层原理
字符串拼接的底层原理
- 等号右边没有变量
public class Test{
public static void main(String[] args){
String s="a"+"b"+"c";
System.out.println(s);
}
}
- 拼接的时候没有变量,都是字符串,触发字符串的优化机制。在编译的时候已经是最终结果了
当我们将java文件编译成class文件的时候,已经变成这样的形式了
public class Test{
public static void main(String[] args){
String s="abc";
System.out.println(s);
}
}
- 等号右边有变量
public class Test{
public static void main(String[] args){
String s1="a";
String s2=s1+"b";
String s3=s2+"c";
System.out.println(s3);
}
}
在jdk8之前版本的情况下!
- main方法压入栈
- 执行
String s1="a";
- 在堆内存中的串池,存储"a"字符串
- 执行`String s2=s1+"a";
- 在串池中存储字符串"b"
- 在堆内存中创建一个StringBuilder对象,里面存储了s1和"a"拼接起来的内容
- 将这个StringBuilder对象通过toString方法转换为String
- 将这个地址赋值给s2
总结:一个加号,堆内存中俩对象(一个StringBuilder一个String)
在jdk8及其之后的版本情况下
public class Test{
public static void main(String[] args){
String s1="a";
String s2="b";
String s3="c";
String s4=s1+s2+s3+s4;
}
}
会先预估一下这些字符串拼接后的长度然后创建对应长度的数组并将字符串存入其中。
字符串拼接的时候有变量参与,在内存中创建很多对象,浪费时间也浪费空间。
故:如果很多字符串变量拼接,不要直接+,因为会在底层创建多个对象,浪费时间和性能。
StringBuilder提高效率的原理
public class Test{
public static void main(String[] args){
StringBuilder sb=new StringBuilder();
sb.append("a");
sb.append("b");
sb.append("c");
}
}
因为StringBuilder是一个内容可变的容器!
上述代码运行是:
- main方法压入栈
- 执行
StringBuilder sb=new StringBuilder();
- 在堆内存中创建一个空间
new StringBuilder()
并将地址值赋值给sb变量,这个空间是内容长度可变的! - 执行append方法并在串池中存储对应字符串
- 将append方法的字符串存入
new StringBuilder
这个地址中
因为StringBuilder是内容可变的容器,故存入时效率很高。不需要创建多个空间
StringBuilder的一些底层
- StringBuilder在创建的时候默认创建一个容量为16的空间
- 添加abc
如果一次性存储的长度大于容量就会,扩容:老容量*2+2
如果超出了默认扩容的大小:就以实际的为准。即添加字符串的长度为容量。
标签:java,String,StringBuilder,s1,---,API,s2,字符串,public From: https://www.cnblogs.com/wdadwa/p/java_API_03.html