👨💻作者简介:👨🏻🎓告别,今天
📔高质量专栏 :☕java趣味之旅
欢迎🙏点赞🗣️评论📥收藏💓关注
💖衷心的希望我的📙作品能给大家带来收获。
🎊前言:
让我们如大自然般🌱悠然自在😊地生活一天吧,
别因为有坚果外壳或者蚊子翅膀落在铁轨上🛤️而翻了车🚆。让我们该起床时🛏️就赶紧起床🛏️,
该休息🛏️时就安心休息🛏️,
保持安宁而没有烦扰的心态;身边的人要来就让他来,要去就让他去,
让钟声🕰️回荡,让孩子👼哭喊—
下定决心好好地过一天。
🙏希望大家都可以过好每一天。也🙏希望我的博客,能给大家带来💯收获。
1. String的进阶方法
1.1 字符串替换
使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:
代码示例: 字符串的替换处理
public static void main(String[] args) {
String str = "hihihello" ;
String ret = str.replace('h','p');//替换所有第一个字符,为第二个参数
System.out.println(ret);
String ret1 = str.replace("hi","ppp");//可以替换字符串
System.out.println(ret1);
String ret2 = str.replaceAll("hi","pt");
System.out.println(ret2);
String ret3 = str.replace("hi","pu");//替换第一个内容
System.out.println(ret3);
System.out.println(str);
}
注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.
1.2 字符串拆分
可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。
可用方法如下:
代码示例: 实现字符串的拆分处理
String str = "hello world hello wanwan";
String[] result = str.split(" ");//分割之后存入数组中
for (String s:result) {
System.out.println(result);
}
代码示例: 字符串的部分拆分
public static void main(String[] args) {
String str = "hello world hello wanwan";
String[] result1 = str.split(" ",2);//limit限定分格几组
for (String s:result1) {
System.out.println(result1);
}//拆分两部分并不是从中间拆分,而是从第一个空格,进行拆分
String[] result2 = str.split(" ",10);
for (String s:result2) {
System.out.println(result2);
}
}
如果分割次数超出最大次数,结果以最大分割次数呈现
代码示例: 拆分IP地址
String str = "192.168.1.1" ;
String[] result = str.split(".") ;
for(String s: result) {
System.out.println(s);
}
String[] result1 = str.split("\\.") ;
for(String s: result1) {
System.out.println(s);
}
String str1 = "192\\168\\1\\1";
String[] ret2 = str1.sqlit("\\\\");
for(String s: result2) {
System.out.println(s);
String str2 = "name=zhangnasan&age=10";
String[] ret3 = str1.sqlit("&|=");
for(String s: result3) {
System.out.println(s);
}
注意事项:
1. 字符"|","*","+"都得加上转义字符,前面加上 "\\" .
2. 而如果是 "\" ,那么就得写成 "\\\\" .
3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.
1.3 字符串截取
从一个完整的字符串之中截取出部分内容。可用方法如下:
代码示例: 观察字符串截取
String str = "helloworld" ;
System.out.println(str.substring(5)); 从指定索引截取到结尾
System.out.println(str.substring(0, 5));截取部分内容
注意事项:
1. 索引从0开始.这里如果传入的是0下标,那么默认回原来的对象
2. 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标
1.4 其他操作方法
代码示例: 观察trim()方法的使用
String str = " hello world " ;
System.out.println("["+str+"]");
System.out.println("["+str.trim()+"]")
trim 会去掉字符串开头和结尾的空白字符(空格, 换行, 制表符等).
代码示例: 大小写转换
String str = " hello%$$%@#$%world 哈哈哈 " ;
System.out.println(str.toUpperCase());
System.out.println(str.toLowerCase());
这两个函数只转换字母。
2. 字符串的特性
2.1 字符串的不可变性
String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,是因为:
1. String类在设计时就是不可改变的,String类实现描述中已经说明了
以下来自JDK1.8中String类的部分实现:
String类中的字符实际保存在内部维护的value字符数组中,该图还可以看出:
1. String类被final修饰,表明该类不能被继承
2. value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。//通过第三张图可以看出
2.所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象
【纠正】网上有些人说:字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变。
这种说法是错误的,不是因为String类自身,或者其内部value被final修饰而不能被修改。
final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。
public static void main(String[] args) {
final int array[] = {1,2,3,4,5};
array[0] = 100;
System.out.println(Arrays.toString(array));
// array = new int[]{4,5,6}; // 编译报错:Error:(19, 9) java: 无法为最终变量array分配值
}
那如果想要修改字符串中内容,该如何操作呢?
2.2 字符串修改
注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下。
public static void main(String[] args) {
String s = "hello";
s += " world";
System.out.println(s); // 输出:hello world
}
但是这种方式不推荐使用,因为其效率非常低,中间创建了好多临时对象。
public static void main(String[] args) {
long start = System.currentTimeMillis();
String s = "";
for(int i = 0; i < 10000; ++i){
s += i;
}
long end = System.currentTimeMillis();//获取当前系统的时间戳
System.out.println(end - start);
start = System.currentTimeMillis();
StringBuffer sbf = new StringBuffer("");
for(int i = 0; i < 10000; ++i){
sbf.append(i);
}
end = System.currentTimeMillis();
System.out.println(end - start);
start = System.currentTimeMillis();
StringBuilder sbd = new StringBuilder();
for(int i = 0; i < 10000; ++i){
sbd.append(i);
}
end = System.currentTimeMillis();
System.out.println(end - start);
}
可以看待在对String类进行修改时,效率是非常慢的,因此:尽量避免对String的直接需要,如果要修改建议尽量使用StringBuffer或者StringBuilder。
b. 借助StringBuffer 和 StringBuilder
3. StringBuilder和StringBuffer
3.1 StringBuilder的介绍
由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。这两个类大部分功能是相同的,这里介绍 StringBuilder常用的一些方法
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("hello");
StringBuilder sb2 = sb1;
// 追加:即尾插-->字符、字符串、整形数字
sb1.append(' '); // hello
sb1.append("world"); // hello world
sb1.append(123); // hello world123
System.out.println(sb1); // hello world123
System.out.println(sb1 == sb2); // true
System.out.println(sb1.charAt(0)); // 获取0号位上的字符 h
System.out.println(sb1.length()); // 获取字符串的有效长度14
System.out.println(sb1.capacity()); // 获取底层数组的总大小
sb1.setCharAt(0, 'H'); // 设置任意位置的字符 Hello world123
sb1.insert(0, "Hello world!!!"); // Hello world!!!Hello world123
System.out.println(sb1);
System.out.println(sb1.indexOf("Hello")); // 获取Hello第一次出现的位置
System.out.println(sb1.lastIndexOf("hello")); // 获取hello最后一次出现的位置
sb1.deleteCharAt(0); // 删除首字符
sb1.delete(0,5); // 删除[0, 5)范围内的字符
String str = sb1.substring(0, 5); // 截取[0, 5)区间中的字符以String的方式返回
System.out.println(str);
sb1.reverse(); // 字符串逆转
str = sb1.toString(); // 将StringBuffer以String的方式返回
System.out.println(str);
}
3.2 StringBuilder常用的一些方法
1. StringBuff append(String str) 方法
作用:在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、
double、float、int、long、Object、String、StringBuff的变量
可以看出,StringBuilder、StringBuffer都没有产生新的对象,另一方面,源码也可以看出。如下图
2.char charAt(int index)
作用:获取index位置的字符
StringBuffer stringBuffer = new StringBuffer("112233445566");
Character character = stringBuffer.charAt(3);//2
3. int length()
作用:获取字符串的长度
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.length());//12
4. void ensureCapacity(int mininmumCapacity)
作用:扩容
5. void setCharAt(int index, char ch)
作用:将index位置的字符设置为ch
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
stringBuffer.setCharAt(2,'a');
System.out.println(stringBuffer);//11a233445566
6. int indexOf(String str)
作用:返回str第一次出现的位置
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.indexOf("2"));//2
System.out.println(stringBuffer.indexOf("22"));//2
System.out.println(stringBuffer.indexOf("222"));// 没有返回-1
7. int indexOf(String str, int fromIndex)
作用:从fromIndex位置开始查找str第一次出现的位置,不包括当前位置
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.indexOf("2",2));//2
System.out.println(stringBuffer.indexOf("2",3));//3
8. int lastIndexOf(String str)
作用:返回最后一次出现str的位置
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.lastIndexOf("1"));//1
System.out.println(stringBuffer.lastIndexOf("11"));//0
9. int lastIndexOf(String str, int fromIndex)
作用:从fromIndex位置开始找str最后一次出现的位置,包括当前位置
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.lastIndexOf("2", 2));//2
System.out.println(stringBuffer.lastIndexOf("2", 3));//3
System.out.println(stringBuffer.lastIndexOf("2", 4));//3
10. StringBuff insert(int offset, String str)
作用:在offset位置插入:八种基类类型 & String类型 & Object类型数据
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.insert(3, "aa"));//112aa233445566
11. StringBuffer deleteCharAt(int index)
作用:删除index位置字符
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.deleteCharAt(3));//11233445566
12. StringBuffer delete(int start, int end)
作用:删除[start, end)区间内的字符
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.delete(2, 8));//11566
13. StringBuffer replace(int start, int end, String str)
作用:将[start, end)位置的字符替换为str
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.replace(0, 8,"ss"));//ss5566
14. String substring(int start)
作用:从start开始一直到末尾的字符以String的方式返回,不包括当前位置
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.substring(3));//233445566
15. String substring(int start,int end)
作用:将[start, end)范围内的字符以String的方式返回
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.substring(2, 6));//2233
16. StringBuffer reverse()
作用:反转字符串
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("112233445566");
System.out.println(stringBuffer.reverse());//665544332211
17. String toString()
作用:将所有字符按照String的方式返回
以上就是所有的常用方法,还需理解并掌握
3.3 String和StringBuilder、StringBuffer的区别
1.String可以直接创建对象,StringBuilder、StringBuffer都不能直接创建对象 ,
2.String的内容无法修改,而StringBuffer和StringBuilder的内容都是可变的,可以修改的
从上述例子可以看出:String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder。
String str = "test";
StringBuffer stringBuffer = new StringBuffer(str);
String str1 = stringBuffer.toString();
System.out.println(str1);//test
StringBuilder stringBuilder = new StringBuilder(str);
StringBuffer stringBuffer1= new StringBuffer();
stringBuffer1.append(str);
System.out.println(stringBuffer1);//test
System.out.println(stringBuffer);//test
System.out.println(stringBuilder);//test
System.out.println(str);//test
注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:
- String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
- StringBuilder变为String: 调用toString()方法
3.4 面试题:
1. String、StringBuffer、StringBuilder的区别
- String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
- StringBuffer与StringBuilder大部分功能是相似的
- StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作
StringBuffer带有synchronized是使用在多线程情况下,保证了线程安全,一个一个的进行,但是频繁的上锁和解锁是需要耗费资源的。
2. 以下总共创建了多少个String对象【前提不考虑常量池之前是否存在】
String str = new String("ab"); // 会创建多少个对象
String str = new String("a") + new String("b"); // 会创建多少个对象
3.5 String类oj
对应oj连接:请点击传送