一:String类的基本介绍
二:String的常用方法
三:StringBuilder类和StringBuffer类
一:String类的基本介绍
1.String类表示字符串:在Java中,Sring类是用来操作字符串,比如字符串的拼接,替换,查找,截取等等。
2.String类不能被继承:String类的修饰符是 public final class ,被final修饰的类不能被继承。
3.String类的用法:与字符串的用法一致,即 "xxxx" 。
4.String类是引用类型,本身不储存字符串,
比如这个代码:
public static void main(String[] args) {
String str = "abc";
}
字符串存储的方式如下图所示:
变量str中拿到的是value(稍后解释)的地址,而value拿到的才是储存字符串的地址,字符串储存在堆中的常量池中
5:String类中的value:value是String类中的一个数组名称,用来放置字符串的地方。
6.字符串的不可变性:String是一种不可变对象,字符串中的内容不可改变。
比如:
public static void main(String[] args) {
String str = "abc";
str = "zxcvb";
System.out.println(str);
}
程序运行出来的是:
但这并不是说字符串"abc"就变成了字符串"zxcvb"。
它的内部变化是这样的:
不变的原因:value是被private final 修饰的,private final修饰导致你根本拿不到value的地址,同时在本类中也不能改变其中的内容,所以value指向的字符串的内容无法改变。
上述代码的操作是将value指向的字符串"abc"的地址变成了另一个字符串"zxcvb"的地址,但字符串"abc"没有被改变,依旧存在于常量池中。
二:String的常用方法
2.1 字符串的构造:
//三种常见的构造方法
public static void main(String[] args) {
//使用常量字符串构造 (形式上类似于直接赋值)
String str1 = "abcd";
//通过new String() 构造
String str2 = new String("abcde");
//通过字符数组进行构造
char[] ch = {'a','b','c','d','e','f'};
String str3 = new String(ch);
System.out.println("str1 = "+str1);
System.out.println("str2 = "+str2);
System.out.println("str3 = "+str3);
}
运行结果:
特殊例子:将一个字符串的引用通过赋值的方法给一个正在初始化的字符串中去
public static void main(String[] args) {
String s1 = new String("hello");
String s3 = s1;
System.out.println("s3 = " + s3);
}
程序运行结果是:
内部的变化过程:
这样的最终结果就是s1和s3都指向同一个对象,它们俩都能操作这个对象。
2.2 字符串的比较
1. == 的比较,String是引用类型,这样直接比较是value中地址的比较,返回类型是Boolean类型,地址一样返回true,不一样返回false。
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("world");
String s3 = s1;
System.out.println(s1 == s2);//false
System.out.println(s3 == s2);//false
System.out.println(s1 == s3);//true
}
//结果是 false false true
//因为此时s3与s1指向同一个对象,所以它俩相同
2.Boolean equals 方法的比较,返回类型是Boolean
equals比较的是字符串的内容,内容一样返回true,不一样返回false。
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("world");
String s3 = s1;
System.out.println(s1.equals(s2));//false
System.out.println(s3.equals(s2));//false
System.out.println(s1.equals(s3));//true
}
结果是: false false true
3.int compareTo(String s) 方法比较,返回类型是int
比较方式:从第一个字母开始,按照每一个字母的十进制数字开始比较,若字母相同则比较下一个字母,一旦大小不一样,比较立刻结束,返回差值。
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("world");
String s3 = s1;
System.out.println(s1.compareTo(s2));//-15
System.out.println(s3.compareTo(s2));//-15
System.out.println(s1.compareTo(s3));//0
}
//h的十进制数是104,w的十进制数是119,所以104 - 119 = -15
字母相同,但区分大小写的情况比较:
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("Hello");
String s3 = s1;
System.out.println(s1.compareTo(s2));//32
System.out.println(s3.compareTo(s2));//32
System.out.println(s1.compareTo(s3));//0
}
//h的十进制数是104,H的十进制数是72,104 - 72 = 32
4.int compareToIgnoreCase(String s) 方法比较,返回类型是int
比较方式:与compareTo一致,但是忽略大小写比较。
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("Hello");
String s3 = s1;
System.out.println(s1.compareToIgnoreCase(s2));//0
System.out.println(s3.compareToIgnoreCase(s2));//0
System.out.println(s1.compareToIgnoreCase(s3));//0
}
//因为比较方法忽略了字母的大小写进行比较 所以字母的十进制数一致
2.3 字符串查找
注:字符串的下标默认是从0开始数的,即从左到右
1. char charAt(int index) 方法, 返回index下标上的字符,若index为负数或者越界,则抛出IndexOutOfBoundsException异常。
public static void main(String[] args) {
String s1 = new String("ababcabcd");
char ch = s1.charAt(3);//b
System.out.println(ch);
}
//程序运行结果是 b
2. int IndexOf(int ch)方法,返回字符ch第一次出现的位置,没有返回-1。
public static void main(String[] args) {
String s1 = new String("ababcabcd");
int index = s1.indexOf('c');//对应4下标
System.out.println(index);
}
//程序运行结果:4
3. int IndexOf(int ch, int fromIndex)方法,返回从fromIndex位置开始找,字符ch第一次出现的位置,没有返回-1。
public static void main(String[] args) {
String s1 = new String("ababcabcd");
int index = s1.indexOf('b',2);
System.out.println(index);
}
//这里是从下标为2的位置开始数,也就是第二个字母a开始数出现的第一个字母b,即3下标的位置
//程序运行结果:3
4. int IndexOf(String s)方法,返回字符串s第一次出现的位置,返回的具体位置是字符串中第一个字符的下标,没有返回-1.
public static void main(String[] args) {
String s1 = new String("ababcabcd");
int index = s1.indexOf("abc");
System.out.println(index);
}
//第一个字符串abc出现的位置是从下标2位置开始的,故返回2
//程序运行结果:2
5. int IndexOf(String s,int fromIndex )方法,返回从fromIndex位置开始找,字符串s第一次出现的位置,返回的具体位置是字符串中第一个字符的下标,没有返回-1。
public static void main(String[] args) {
String s1 = new String("ababcabcd");
int index = s1.indexOf("abc",3);
System.out.println(index);
}
//从3下标开始找,字符串abc出现的位置从5开始,故返回5
//程序运行结果:5
6. int lastIndexOf(int ch)方法,从后往前找,找到字符ch第一次出现的位置,返回其下标,此时这里的下标默认是从左往后数的下标,没有返回-1。
public static void main(String[] args) {
String s1 = new String("ababcabcd");
int index = s1.lastIndexOf('a');
System.out.println(index);
}
//从后往前数出现的第一个字母a,即从左往右数出现的第三个字母a,其下标是5
//程序运行结果:5
7. int lastIndexOf(int ch,int fromIndex)方法,从fromIndex位置开始从后往前找,返回字符ch第一次出现的下标,没有返回-1。
public static void main(String[] args) {
String s1 = new String("ababcabcd");
int index = s1.lastIndexOf('a',4);
System.out.println(index);
}
//从4下标,即第一个字母c开始从后往前数出现的第一个字母a,即从左往右数出现的第二个字母a,其下标是2
//程序运行结果:2
8. int lastIndexOf(String s)方法,从后往前找,找到字符串s第一次出现的位置,返回其第一个字母的下标,没有返回-1。
public static void main(String[] args) {
String s1 = new String("ababcabcd");
int index = s1.lastIndexOf("abc");
System.out.println(index);
}
//从后往前找,字符串abc第一次出现的位置从5下标开始的,返回5
//程序运行结果:5
9.int lastIndexOf(String s, int fromIndex)方法,从fromIndex位置从后往前找,返回字符串s第一次出现的位置,没有返回-1。
public static void main(String[] args) {
String s1 = new String("ababcabcd");
int index = s1.lastIndexOf("abc",3);
System.out.println(index);
}
//从3下标开始,返回从后往前找字符串abc第一次出现的位置,其下标是2
//程序运行结果:2
2.4 字符串转化
1. 数字转字符串:String类中的valueOf(数字参数) 方法
public static void main(String[] args) {
String s1 = String.valueOf(134.56);
int a = 123;
String s2 = String.valueOf(a);
String s3 = String.valueOf(true);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
//输出的结果是以字符串的形式输出的
输出结果:
134.56
123
true
2.字符串转数字:
public static void main(String[] args) {
//注:Integer,Double 都是java中的包装类型
int data1 = Integer.parseInt("123456");
Double data2 = Double.parseDouble("12.34");
System.out.println(data1);
System.out.println(data2);
}
//输出的结果是以相对应的类型进行输出的
输出结果:
123456
12.34
3.小写字母转成大写字母:toUpperCase() 方法
public static void main(String[] args) {
String s1 = new String("hello");
System.out.println(s1.toUpperCase());//这里进行了转换
}
输出结果:
HELLO
4.大写字母转成小写字母:toLowerCase() 方法
public static void main(String[] args) {
String s1 = new String("WORLD");
System.out.println(s1.toLowerCase());//这里进行转换
}
输出结果:
world
5. 字符串转数组: toChatArray() 方法
public static void main(String[] args) {
String s1 = new String("hello");
char[] ch = s1.toCharArray();//转换方法
//输出数组中的内容
for (int i = 0; i < ch.length; i++) {
System.out.println(ch[i]);
}
输出结果:
h
e
l
l
o
6 .数组转字符串:与构造方法中通过字符数组进行构造一致
public static void main(String[] args) {
char[] ch = {'a','b','c','d'};
String s1 = new String(ch);
System.out.println(s1);
}
输出结果:
abcd
7. 格式化:String类中的format方法
public static void main(String[] args) {
String s1 = String.format("%d-%d-%d",2024,6,22);
System.out.println(s1);
}
//格式:format("格式化符号-格式化符号-格式化符号",类型,类型,类型);
//格式化符号与类型是对应的,%d对应整型,%c对应字符型等等
//输出结果以" "内的形式输出," "内是什么样的,数值带进去的输出结果就是怎么样的
输出结果:
2024-6-22
2.5 字符串的替换
使用一个指定的新的字符替换掉字符串中已有的字符数据
1. String replace(char oldChar, char newChar) 方法 用指定的新的一个字符 newChar 替换掉字符串中的某一个字符 oldChar
public static void main(String[] args) {
String s = new String("ababcabcd");
String tmp = s.replace('a','k');//这里的参数是单个字符
System.out.println(tmp);
}
//这里是用k字母替换掉字符串中所有的a字母并被tmp接收
输出结果:
kbkbckbcd
2. String replace(CharSequence target, CharSequence replacement) 方法 用指定的连续的几个字符replacement 替换点原字符串中的target
public static void main(String[] args) {
String s = new String("ababcabcd");
String tmp = s.replace("bc","uuu");
System.out.println(tmp);
}
//这里是用uuu字符串替换掉原字符串中所有的bc字符串
输出结果:
abauuuauuud
3. String repalceFirst(String regex, String replacement)方法,是用新的指定的字符数据replacement 替换掉原字符串中首个regex数据,只替换第一个。
public static void main(String[] args) {
String s = new String("ababcabcd");
String tmp = s.replaceFirst("bc","uuu");
System.out.println(tmp);
}
//只用uuu替换掉抵押给bc
输出结果:
abauuuabcd
4.String replaceAll(String regex, String replacement) 方法,这个方法和replace方法的效果一样,但方法本身的方法名,参数类型不一样。
注:因为字符串是不可变对象,所有关于字符串的替换都是在内存中创建了一个新的字符串,在新的字符串上进行的操作,然后输出新的字符串或将新的字符串储存在新的String对象中。
2.6 字符串的拆分
可以将一个完整的字符串按照指定的分隔符划分成若干个子字符串
1. String[] split(String regex) 方法,返回类型是字符串,所有用分隔符拆分之后形成的子字符串需用字符串数组接收。
public static void main(String[] args) {
String s = new String("name=zhangsan&age=20");
String[] strings = s.split("&");//&为分隔符
for (int i = 0; i < strings.length; i++) {
System.out.println(strings[i]);
}
}
//以字符&为分隔符,将&左右分隔成两个字符串,即字符串name=zhangsan和字符串age=20
输出结果:
name=zhangsan
age=20
对代码进行优化,即再用分隔符 = 进行第二次拆分,使代码美观点
public static void main(String[] args) {
String s = new String("name=zhangsan&age=20");
String[] strings = s.split("&");
for (int i = 0; i < strings.length; i++) {
//获取分隔后存在strings数组中的的字符串,然后通过 = 进行分隔
String[] strings1 = strings[i].split("=");
for (int j = 0; j < strings1.length; j++) {
System.out.println(strings1[j]);
}
}
}
//整段代码就是将字符串中的=和&左右两边的字符串都拆分开来,然后存入字符串数组中去
输出结果:
name
zhangsan
age
20
上列代码的改进:
我们可以将多个分隔符通过符号 | (逻辑或) 来写在一起,同时对字符串进行拆分
public static void main(String[] args) {
String s = new String("name=zhangsan&age=20");
String[] strings = s.split("&|=");//split的参数都写在一个" "中
for (int i = 0; i < strings.length; i++) {
System.out.println(strings[i]);
}
//此时split方法中的分隔符为&或者=,即在分割字符串时,只要遇到这两个分割符中的任何一个,都会进行字符串的分割
输出结果:
name
zhangsan
age
20
2. String[] split(String regex, int limit)方法,这个方法与第一个方法基本相同,差别在于你可以规定拆分成limit个字符串,一旦拆分完limit个字符串之后,就会执行下一条语句。
public static void main(String[] args) {
String s = new String("name=zhangsan&age=20");
String[] strings = s.split("&|=",2);
for (int i = 0; i < strings.length; i++) {
System.out.println(strings[i]);
}
}
//split参数中的2表示该字符串只拆分成两个子字符串
输出结果:
name
zhangsan&age=20
3. 特殊字符的拆分
部分特殊字符作为分隔符可能无法正确切分,需要进行转义
如 "." "\" "+" "*" "|" 等等字符在字符串时,若以这些字符为分隔符进行拆分,需要转义
注:在java中 \\ 才表示 / ,即两个\\才能表示为一个\
例1:
public static void main(String[] args) {
String s = new String("1.2.3.4");
String[] strings = s.split("\\.");
for (int i = 0; i < strings.length; i++) {
System.out.println(strings[i]);
}
}
//这里的字符 . 作为分隔符,若只写 . 是无法对字符串进行拆分的,需要进行转义
//转义字符\需要两个\\才能表示一个\
输出结果:
1
2
3
4
例2:
public static void main(String[] args) {
String s = new String("1.2\\3.4");
String[] strings = s.split("\\\\");
for (int i = 0; i < strings.length; i++) {
System.out.println(strings[i]);
}
}
//字符串1.2\\3.4 实际上是1.2\3.4
//分隔符\\\\实际上是\ \ ,即以\为分割符需要用转义字符 \ 来进行修饰
输出结果 :
1.2
3.4
2.7 字符串的截取
从一个完整的字符串中截取出部分内容
1. String substring(int beginIndex) 方法,从beginIndex位置(下标)开始截取到结尾。
public static void main(String[] args) {
String s = new String("HelloWorld");
String str = s.substring(5);
System.out.println(str);
}
//这个代码说明从5下标开始截取字符串到结尾,即从字符W开始
输出结果:
World
2. String substring(int beginIndex, int endIndex) 方法,从beginIndex位置开始截取,截取到endIndex位置前的一个字符,即[beginIndex, endIndex)。java中的涉及取值范围的基本都是左闭右开。
public static void main(String[] args) {
String s = new String("HelloWorld");
String str = s.substring(2,8);
System.out.println("str = "+str);
}
//substring(2,8)说明包含2下标,不包含8下标,即从2下标开始截取到7下标
输出结果:
str = lloWor
2.8. 字符串去左右空白字符
String strip() 方法,能去除字符在右边两边的空白字符(如空格,换行符,制表符),但不能去除处于字符串内的空白字符。
public static void main(String[] args) {
String s = new String(" he llo wor ld ");
System.out.println("s =" + s);
String str = s.strip();//进去去除空白字符
System.out.println("str =" + str);
}
输出结果:
s = he llo wor ld
str =he llo wor ld
2.9 获取字符串的长度
与数组获取数组长度方法一致,不过length后是(),而不是[ ]。
public static void main(String[] args) {
String s = new String("hello");
System.out.println(s.length());//length后跟()
}
//程序运行结果是:5
注:因为String类字符串的不可变性,所有涉及修改字符串内容的操作都是创建一个新对象,改变的是新对象。
三:StrnigBuilder类和StringBuffer类
StringBuilder类和StringBuffer类 是java提供的能对字符串修改的另外两个类 ,不是String类,但能操作String类。
1.StringBuilder和StringBuffer 与 String 的区别
如:String类的字符串内容是不变的,在对其进行修改时会创建新的字符串去修改,而不会修改原来的字符串。
public static void main(String[] args) {
String s = new String("hello");
s += "world";
System.out.println(s);
}
//程序运行下来共创建了三个对象
内部运行过程:
由上图可知在利用String类对字符串进行修改时会频繁的创建新的对象,效率是非常慢的。
=============================
此时引出StringBuilder和StringBuffer。
这两个类对字符串的修改是在字符串本身上修改的,不会创建新的对象,大大提高了效率。
以StringBuffer举例部分方法:
3.1 尾部数据增加
StringBuff append(String s) 方法,在尾部追加,相当于String的 += 。且操作的对象始终只有一个,那就是字符串本身。
public static void main(String[] args) {
StringBuffer str = new StringBuffer("hello");
str.append(123);
System.out.println("str = "+str);
str.append("world");
System.out.println("str = "+str);
}
//这个str始终都是它自己,对字符串的操作都是发生的自己身上的,没有新建对象,所以效率会快很多。
//而且增加的内容是在数据尾部增加的。
输出结果:
str = hello123
str = hello123world
3.2 反转字符串
StringBuff reverser() 方法,能将字符串逆置过来。
public static void main(String[] args) {
StringBuffer str = new StringBuffer("hello");
str.reverse();
System.out.println(str);
}
//这里直接用str调用了reverser方法,没有用变量去接收它
//间接说明了StringBuffer类操作字符串是在本身上操作的
输出结果:
olleh
3.3 数据的插入
StrignBuff insert(int offset, String str) 方法,在offset位置插入:八种数据类型&String类型&Object类型。
public static void main(String[] args) {
StringBuffer str = new StringBuffer("hello");
str.insert(2,12);
System.out.println(str);
StringBuffer str1 = new StringBuffer("hello");
str1.insert(2,"abc");
System.out.println(str1);
}
//在2下标插入12
//在2下标插入abc
输入结果:
he12llo
heabcllo
3.4 设置字符
void setCharAt(int index, char ch) 方法,将index位置的字符设置成指定的字符ch。
public static void main(String[] args) {
StringBuffer str = new StringBuffer("hello");
str.setCharAt(2,'o');
System.out.println(str);
}
//将2下标的字符l设置成字符o
输出结果:
heolo
3.5 删除字符
(一):StringBuff deleteCharAt(int index)方法,删除index位置的字符。
public static void main(String[] args) {
StringBuffer str = new StringBuffer("hello");
str.deleteCharAt(2);
System.out.println(str);
}
//删除2下标的字符l
输出结果:
helo
(二):StringBuff delete(int index, int end)方法,删除区间[index,end)的字符
public static void main(String[] args) {
StringBuffer str = new StringBuffer("hello");
str.delete(1,4);
System.out.println(str);
}
//删除区间[1,4)下标的字符,就下标1,2,3的字符删除
输出结果:
ho
3.6 字符串替换
StringBuff replace(int start, int end, String s)方法,将区间[strat, end)的字符替换成字符串s。
public static void main(String[] args) {
StringBuffer str = new StringBuffer("hello");
str.replace(1,3,"uuu");
System.out.println(str);
}
//将区间[1,3)的字符,即字符串el替换成字符串uuu
输出结果:
huuulo
3.7 返回字符串
String toString()方法,将所有字符以String类型返回。
public static void main(String[] args) {
StringBuffer str = new StringBuffer("hello");
str.toString();//将StringBuffer转换为String类型数据
System.out.println(str);
}
//StringBuffer不是String类型
//输出结果为:hello