String类
概述
在Java中 字符串时最广泛应用的数据,Java提供了String、StringBuffer、StringBuilder类 来创建和操作字符串。并且在Java中,字符串被当作对象来处理,字符串时引用类型
字符串不可修改的原因
public final class String
implements java. io. Serializable, Comparable < String > , CharSequence {
private final char value[ ] ;
private int hash;
private static final long serialVersionUID = - 6849794470754667710L ;
. . . . . . .
}
String 对象的字符内容存储在被 private和final 修饰的 字符数组中,即value[] private 意味着外面无法直接获取字符数组,而String没有提供value的 get 和 set 方法 final 一位置字符数组的引用不可改变,即不可通过让 value 指向新的数组对象来实现修改String对象;而String 也没哟提供方法来修改value数组某个元素值,因此字符串的字符数组内容也不可变
字符串修改结果方式
字符串的拼接 字符串的截取 字符串的替换 特点:每次都需要创建一个新的char数组表示修改结果
字符串内存分析
字面量
每一个字面量都是一个String对象
新建字符串对象
使用new创建字符串对象
public class Demo {
public static void main ( String [ ] args) {
String s1 = "Hello word" ;
String s2 = new String ( "Hello2" ) ;
}
}
字符串存储分析
字符串常量保存在常量池中
编译代码时,编译程序会将所用常量都保存在 方法区中的常量池里。因此,相同常量的所有对象,实际上就是存储与常量池中的同一个对象 常量池中相同的字符串可共享
public class Demo {
public static void main ( String [ ] args) {
String s1 = "Hello word" ;
String s2 = "Hello word" ;
String s3 = "hel" ;
System . out. println ( "字符串常量在常量池,相同值:" + ( s1== s2) ) ;
System . out. println ( "不相同值:" + ( s1== s3) ) ;
}
}
字符串常量在常量池,相同值:true
不相同值:false
public class Demo {
public static void main ( String [ ] args) {
String s1 = "Hello word" ;
String s2 = new String ( "Hello word" ) ;
System . out. println ( "存储区域不同:" + ( s1== s2) ) ;
}
}
存储区域不同: false
字符串的存储分布图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HgUy1BNb-1678341301021)(G:\Java-栈\常用类\常量与对象内存图.PNG)]
字符串的拼接
public class Demo {
public static void main ( String [ ] args) {
String s1 = "Hello" ;
String s2 = " word" ;
String s3 = s1 + s2;
String s4 = "Hello" + " word" ;
String s5 = s1 + " word" ;
String s6 = "Hello" + " word" ;
String s7 = s1 + s2;
System . out. println ( s3) ;
System . out. println ( s4) ;
System . out. println ( s5) ;
System . out. println ( "-----------" ) ;
System . out. println ( s3== s4) ;
System . out. println ( s4== s5) ;
System . out. println ( s3== s5) ;
System . out. println ( s4== s6) ;
System . out. println ( s3== s7) ;
System . out. println ( "-------------" ) ;
String s8 = ( s1+ s2) . intern ( ) ;
System . out. println ( s8== s4) ;
}
}
Hello word
Hello word
Hello word
-- -- -- -- -- -
false
false
false
true
false
-- -- -- -- -- -- -
true
Process finished with exit code 0
小结1:
常量与常量的拼接结果在常量池 拼接的两者中只要其中有一个是变量,结果就在堆中 拼接的结果调用intern() 方法,就在常量池中
比较字符串
String类中重写了equals 方法,使用自付出的内日你哥来比较两个对象
public class Demo2 {
public static void main(String[] args) {
String sr1 = "work";
String sr2 = new String("work");
System.out.println("比较引用地址:"+(sr1==sr2));
System.out.println("比较内容:"+sr1.equals(sr2));
}
}
常用方法
1.创建字符串
public class Demo3 {
public static void main ( String [ ] args) {
byte [ ] buf = { 97 , 98 , 99 } ;
String str = new String ( buf) ;
String str2 = new String ( buf, 1 , 2 ) ;
System . out. println ( str) ;
System . out. println ( str2) ;
System . out. println ( "-----------------" ) ;
char [ ] chars = { '1' , '6' , '号' , '放' , '假' } ;
String string = new String ( chars) ;
String string1 = new String ( chars, 0 , 3 ) ;
System . out. println ( string) ;
System . out. println ( string1) ;
System . out. println ( "------------------" ) ;
String string2 = new String ( "abcde" ) ;
System . out. println ( string2) ;
System . out. println ( "---------------" ) ;
int [ ] arr = { 98 , 99 , 100 } ;
String string3 = new String ( arr, 0 , 3 ) ;
System . out. println ( string3) ;
}
}
abc
bc
-- -- -- -- -- -- -- -- -
16 号放假
16 号
-- -- -- -- -- -- -- -- --
abcde
-- -- -- -- -- -- -- -
bcd
Process finished with exit code 0
2.length()
public class Demo4 {
public static void main(String[] args) {
String s = "abdjdsl";
System.out.println("长度:"+s.length());//长度方法
}
}
//结果
长度:7
Process finished with exit code 0
3.字符串转换为字节数组或字符数组
public char[] toCharArray() public byte[] getByte()
public class Demo4 {
public static void main ( String [ ] args) {
String s = "abdjdsl" ;
char [ ] charArray = s. toCharArray ( ) ;
System . out. println ( "字符数组:\n" + Arrays . toString ( charArray) ) ;
System . out. println ( "-------------" ) ;
byte [ ] buf = s. getBytes ( ) ;
System . out. println ( "字节数组:\n" + Arrays . toString ( buf) ) ;
}
}
字符数组:
[ a, b, d, j, d, s, l]
-- -- -- -- -- -- -
字节数组:
[ 97 , 98 , 100 , 106 , 100 , 115 , 108 ]
Process finished with exit code 0
4,大小写转换
public String toUpperCase() public String toLowerCase()
public class Demo4 {
public static void main ( String [ ] args) {
String s = "abABCl" ;
System . out. println ( "转大写:\n" + s. toUpperCase ( ) ) ;
System . out. println ( "转小写:\n" + s. toLowerCase ( ) ) ;
}
}
转大写:
ABABCL
转小写:
ababcl
5.实现字符串的链接
(+)
字符串和热议类型之间使用 ”+“ ,所有基本类型都转为字符串,所有引用类型都会调用toString() ,最后在执行字符串链接
public class Demo4 {
public static void main ( String [ ] args) {
int age = 7 ;
String s = "He is " + age + " years old" ;
System . out. println ( s) ;
}
}
He is 7 years old
Process finished with exit code 0
public String concat(String str)方法
public class Demo4 {
public static void main ( String [ ] args) {
int age = 7 ;
String s = "He is " . concat ( String . valueOf ( age) ) . concat ( " years old." ) ;
System . out. println ( s) ;
String s2 = "He is " . concat ( age+ "" ) . concat ( " years old." ) ;
System . out. println ( s2) ;
}
其他类型转换为字符串的两种方法
String.valueOf(参数类型 参数) “”+参数 参数+“”
6.public String trim()
public class Demo4 {
public static void main(String[] args) {
String s = " Hello word ";
System.out.println("原来:"+s);
System.out.println("现在:"+s.trim());
}
}
//结果
原来: Hello word
现在:Hello word
Process finished with exit code 0
7.判断相关方法
方法声明 方法作用 public boolean equals(Object obj) 比较字符串内容是否相同,且区分大写 public boolean equalsIgnoranceCase(String art) 比较字符串内容是否相同,忽略大小写 public boolean contians(String str) 判断字符串是否包含另一个字符串 public boolean startsWith(String str) 判断字符串是否以指定字符串开头 public boolean endsWIth(String str) 判断字符串是否以指定字符串结尾 public boolean isEmpty() 判断字符串是否为空
public class Demo4 {
public static void main ( String [ ] args) {
String s = "abc" ;
byte [ ] buf = { 97 , 98 , 99 , 100 } ;
String s2 = new String ( buf) ;
System . out. println ( s2) ;
System . out. println ( "比较字符串内容是否相同 区分大小写:" + s. equals ( s2) ) ;
System . out. println ( "比较字符串内容是否相同 不区分大小写:" + s. equalsIgnoreCase ( s2) ) ;
System . out. println ( "s2是否包含s:" + s2. contains ( s) ) ;
System . out. println ( "s2是否以s开头:" + s2. startsWith ( s) ) ;
System . out. println ( "s2是否以s结尾:" + s2. endsWith ( s) ) ;
System . out. println ( "s2是否为空:" + s2. isEmpty ( ) ) ;
}
}
abcd
比较字符串内容是否相同 区分大小写:false
比较字符串内容是否相同 不区分大小写:false
s2是否包含s: true
s2是否以s开头: true
s2是否以s结尾: false
s2是否为空: false
Process finished with exit code
8.字符串的定位
方法声明 方法作用 public char charAt(int index) 获取执行索引值的字符 public int indexOf(char ch)// 返回此字符在字符串中第一次 出现的索引值,如果都不匹配则返回-1 public int indexOf(String str) 返回指定字符串在字符串中第一次 出现的索引值,如果都不匹配则返回-1 public int lastIndexOf(int ch) 返回指定字符在字符串中最后一次 出现的索引值,如果都不匹配则返回-1 public int lastIndexOf(iString str) 返回指定字符串在字符串最后一次 出现的索引值,如果都不匹配则返回-1
public class Demo4 {
public static void main ( String [ ] args) {
int [ ] arry = { 97 , 98 , 99 , 100 , 97 , 98 , 99 , 100 } ;
String str = new String ( arry, 0 , 8 ) ;
System . out. println ( str) ;
char ch = str. charAt ( 0 ) ;
System . out. println ( "指定索引值的字符" + ch) ;
int count1 = str. indexOf ( 'b' ) ;
System . out. println ( "字符b第一次出现的位置:" + count1) ;
int count2 = str. indexOf ( "abd" ) ;
System . out. println ( "字符串abd第一次出现的位置:" + count2) ;
int count3 = str. lastIndexOf ( 'd' ) ;
System . out. println ( "字符b最后第一次出现的位置:" + count3) ;
int count4 = str. lastIndexOf ( "abc" ) ;
System . out. println ( "字符串abc最后第一次出现的位置:" + count4) ;
}
}
abcdabcd
指定索引值的字符a
字符b第一次出现的位置:1
字符串abd第一次出现的位置: - 1
字符b最后第一次出现的位置:7
字符串abc最后第一次出现的位置: 4
Process finished with exit code 0
9.替换
方法声明 方法作用 public String replace(char old,char new) 替换指定的字符
public class Demo4 {
public static void main(String[] args) {
char[] chars = {'a','b','c','d','d'};
String str = new String(chars);
System.out.println(str);
String strNew = str.replace('d','1');
System.out.println("将字符d替换成字符1:"+strNew);
}
}
//结果
abcdd
将字符d替换成字符1:abc11
Process finished with exit code
10.获取子串
方法声明 方法作用 public String subString(int start) 指定位置开始截取字符串,直到末尾 [start,lenght) public String subString(int start,int end) 截取指定范围内的字符串 [start,end)
public class Demo4 {
public static void main(String[] args) {
String str = "我是真的是你爹";
System.out.println(str);
String st1 = str.substring(2);
System.out.println("从下标为2开始,到结束:"+st1);
String st2 = str.substring(4,6);
System.out.println("从下标为4-6截取:"+st2);
}
}
//结果
我是真的是你爹
从下标为2开始,到结束:真的是你爹
从下标为4-6截取:是你
Process finished with exit code 0
11.比较字符串
方法声明 方法作用 public int compareTo(String str) 按字典顺序进行比较,区分大小写 (做减法,调用对象-比较对象) public int compareToIgnoreCase(String str) 按字典顺序进行比较,忽略大小写 (做减法,调用对象-比较对象)
public class Demo4 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "ABCD8";
int count1 = s1.compareTo(s2);
System.out.println("s1与s2比较,区分大小写:" + count1);
int count2 = s1.compareToIgnoreCase(s2);
System.out.println("s1与s2比较,忽略大小写:" + count2);
}
}
//结果
s1与s2比较,区分大小写:32
s1与s2比较,忽略大小写:-2
Process finished with exit code 0
12.拆分字符串
方法声明 方法 public String[] split(String regex) 分割字符串为一个字符串数组。通常使用逗号
public class Demo4 {
public static void main(String[] args) {
String str = "2003,2,10";
System.out.println(str);
String[] strArray = str.split(",");
System.out.println(Arrays.toString(strArray));
}
}
//结果
2003,2,10
[2003, 2, 10]
Process finished with exit code 0
13.将其他数据转换为字符串
方法声明 方法作用 public static String valueOf(boolean b) 返回boolean 参数的字符串表示形式 public static String valueOf(char c) 返回char 参数的字符串表示形式 public static String valueOf(char[] cArray) 返回char数组 参数的字符串表示形式 public static String valueOfchar[] cArray,int offset,int count) 返回char数组参数的特定子数组的字符串表示形式 public static String valueOf(double d) 返回double 参数的字符串表示形式 public static String valueOf(float f) 返回float参数的字符串表示形式 public static String valueOf(int i) 返回int 参数的字符串表示形式 public static String valueOf(long l) 返回long参数的字符串表示形式 public static String valueOf(Object obj) 返回Object 参数的字符串表示形式
StringBuffer类
1.理解
由于String的内容是不可变的,在频繁操作字符串的应用中,导致String对象泛滥,不断地被创建和销毁,占用大量的内存和cpu时间
public class Demo4 {
public static void main ( String [ ] args) {
Date date = new Date ( ) ;
String result = "" ;
for ( int i = 0 ; i < 100000 ; i++ ) {
result += "A" ;
}
}
}
这将创建100000个对象,其中-99999个对象是临时对象,是计算的中间结果。JVM 需要花费大量的内存来存放,也需要大量的CPU时间来回收对象。
因此,通过使用可变的字符串缓冲区类(StringBuffer) 来完成类似的 工作:
public class Demo4 {
public static void main(String[] args) {
Date date = new Date();
StringBuffer buffer = new StringBuffer(100*1024);
for (int i = 0; i < 100000; i++) {
buffer.append("A");
}
String result = buffer.toString();
}
}
2.缓冲原理
StringBuffer 对象内部有一个缓冲区,默认缓冲区的容量是 16字节 通过String Buffer de append()方法 向缓冲区中不断追加数据,当数据的大小超过缓冲区的大小时,系统会重新创建一个原来缓冲区的一倍大的新缓冲区,并将原缓冲区中的数据拷贝到新缓冲区中,这个操作非常好资源。 因此,需要预估数据所占空间大小,在创建缓冲区时 与分配最大值,防止重新创建缓冲区,提高系统性能
1.拼接字符串
public class Demo4 {
public static void main ( String [ ] args) {
String st1 = "Hello" ;
String st2 = "word" ;
String st3 = "Yunnan" ;
String st4 = st1 + st2;
String st5 = st4 + st3;
System . out. println ( st5) ;
}
}
public class Demo4 {
public static void main ( String [ ] args) {
String st1 = "Hello" ;
String st2 = "word" ;
String st3 = "Yunnan" ;
StringBuffer buffer = new StringBuffer ( 1024 ) ;
buffer. append ( st1) . append ( st2) . append ( st3) ;
String st4 = buffer. toString ( ) ;
System . out. println ( st4) ;
}
}
这个方法只需要创建一个StringBuffer 对象,不需要额外创建对象,最后直接缓冲区中的值为一个字符串。
特点:一次性分配缓冲 之后不需要再创建额外的临时变量,整个性能会非常高
3.常用方式
创建一个StringBuffer对象 使用append 增加数据
xxxxxxxxxx public class Demo4 { public static void main(String[] args) { String st1 = "Hello"; String st2 = "word"; String st3 = "Yunnan"; StringBuffer buffer = new StringBuffer(1024);//缓冲区初始值大小 buffer.append(st1).append(st2).append(st3); String st4 = buffer.toString();//toString()获得字符串 System.out.println(st4); }}
4.方法
1.添加
方法声明 方法作用 StingBuffer() 无参构造器 StringBuffer(int capacity) 指定容量的字符串缓冲类(缓冲区域空间大小) 构造器 StringBuffer(String str) 指定字符串内容缓冲对象 StringBuffer append(xxx) 在缓冲区的尾部添加新的文本对象,它支持任意类型,都自动被转换为字符串 StringBuffer insert(int offset,xxx) 在指定的索引位置添加新的文本对象
2.查看
方法声明 方法作用 int capacity() 返回当前容量 int length() 返回长度(字符数) int indexOf(String str) 返回第一次出现的指定字符串在该字符串中的索引 String subString(int strat) 从指定位置截取到末尾 String subString(int start,int end) 截取start 到 end的字符串,[start,end) String toString() 返回StringBuffer 中的字符串
3.修改
方法声明 方法作用 StringBuffer replace(int start,int end,String str) 指定字符串替换子串,[start,end) setCharAt(int index,char ch) 替换指定位置中的字符
4.删除
方法声明 方法作用 StringBuffer deleteChar(int index) 删除指定的位置的字符,并返回本身 StringBuffer delete(int start,int end) 删除从从指定位置开始,指定位置结束的内容,[strat,end)
5.反序
方法声明 方法作用 StringBuffer reserve() 字符串反转
区别
String StringBuffer和StringBuilder
String StringBuffer StringBuilder JDK版本 JDK1.0 JDK1.0 JDK1.5 线程安全 是 是 否 效率 低 中 高 值可变性 否 是 是
偏移量
偏移量的意思是前面几个不要 单词:offset 例:偏移量=2,前面2个不要 从第三个开始
自动扩容的方式
ex) | 删除指定的位置的字符,并返回本身 | | StringBuffer delete(int start,int end) | 删除从从指定位置开始,指定位置结束的内容,[strat,end) |
5.反序
方法声明 方法作用 StringBuffer reserve() 字符串反转
区别
String StringBuffer和StringBuilder
String StringBuffer StringBuilder JDK版本 JDK1.0 JDK1.0 JDK1.5 线程安全 是 是 否 效率 低 中 高 值可变性 否 是 是
偏移量
偏移量的意思是前面几个不要 单词:offset 例:偏移量=2,前面2个不要 从第三个开始