❤️❤️前言~????
hellohello~,大家好??,这里是E绵绵呀✋✋ ,如果觉得这篇文章还不错的话还请点赞❤️❤️收藏? ? 关注??,如果发现这篇文章有问题的话,欢迎各位评论留言指正,大家一起加油!一起chin up!??
?个人主页:E绵绵的博客
?所属专栏:JAVASE题目练习 JAVASE知识点专栏 c语言知识点专栏 c语言题目练习
在String类的第二部分中我们将给大家介绍如何真正修改字符串内容以及讲解一些题目。
那么开始吧!
字符串修改
❤️❤️注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,我们对其修改都会创建新对象,导致效率非常低下。
所以我们这就出现了StringBuilder类或者StringBuffer类。
下面我们拿StringBuilder类举例:
如上图其类内部也包含着数组,但其修饰并不是用private以及final修饰,所以其内部可以被修改,当我们修改该类对象时,不会创建新对象而是修改原本的对象的值。所以用它修改字符串时效率较高。
下面请看实例
public class Main {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); //直接修改String类对象所用时间 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); //用StringBuffer类间接修改String对象所用时间 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); //用StringBuilder类间接修改String对象所用时间 }}
我们由上图可知——各个方法对字符串修改100次所花费的时间,直接修改为经历了255毫秒,间接修改为经历了1毫秒.
这是因为直接修改会创建非常多的对象,导致效率变低很多,而我们用这两个类其中一个类间接修改都是从始至终就只有该类对象里面的数组值在不断变换,并不会创建新对象,所以效率很高
❤️❤️因此:尽量避免对String的直接需要,如果要修改字符串建议尽量 使用StringBuffer或者StringBuilder。
那么接下来我们将给大家介绍怎么使用Stringbuffer,StringBuilder。
??StringBuilder和StringBuffer的使用
❤️❤️StringBuilder和StringBuffer其实大部分功能是相似的,所以我们只要讲其中一个类的使用,另一个类的使用也是跟它大差不差几乎相同的(区别我们之后讲)。
那我们就讲下StringBuilder的使用:
??StringBuilder是Java中的一个类,用于处理字符串的可变序列。它的创建如下:
使用关键字new创建一个StringBuilder对象:
如果参数为空,StringBuilder的初始内容就不存在,相当于内部字符数组不含任何字符。
StringBuilder sb = new StringBuilder();
我们还可以选择在创建StringBuilder对象时传入一个初始字符串,该字符串将成为StringBuilder的初始内容,相当于其内部的字符数组存在着该字符串的字符.
StringBuilder sb = new StringBuilder("Hello");
那么这就是其创建StringBuilder对象的一些方法
??下面我们讲一下其类中的两个重要方法。(必记)
StringBuilder类中的append()方法向StringBuilder对象中添加字符串,如下:
使用后该StringBuilder对象sb内容尾部将添加World。相当于其字符数组在最后面加了这五个字符.注意因为不用创建新对象,所以我们也无需创建引用去接收它,直接使用该方法就能达成在尾部添加字符串的效果,如下:
sb.append("World");
StringBuilder类中的toString()方法是创建一个String类型,字符串内部是StringBuilder对象内部字符数组的全部字符,并返回该字符串,所以我们需要创建一个字符串引用去接收它。
String result = sb.toString();
除此之外该类中还存在很多方法,不过我们这里就不再多讲了,你们自己看下面的图,注意有些直接使用方法就能达成其效果,有些要创建引用去接收才行。
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!!!"); //在0位置上插入字符串hello world!!! System.out.println(sb1); //Hello world!!!Hello world123 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); }
从上述例子可以看出:
String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder。
注意:String和StringBuilder类不能直接转换(不存在继承关系)。如果要想互相转换,可以采用如下原则:
String变为StringBuilder:利用StringBuilder的构造方法或append()方法
StringBuilder变为String: 调用toString()方法。
注意StringBuilder和StringBuffer大部分功能相似,所以StringBuffer也是可以用以上方法去创建对象和使用如上图一样的方法。几乎StringBuilder能做的StringBuffer都能做。
❤️❤️所以这样就可以通过不断追加字符串来构建一个可变的字符串。StringBuilder和StringBuffer相比于String类的优势在于,它可以避免频繁创建新的字符串对象,提高了字符串拼接的效率。
String、StringBuffer、StringBuilder的区别
❤️❤️区别:
1.String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
2.StringBuffer与StringBuilder大部分功能是相似的,但其还是有一点点区别的,如下:
3.StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作。
线程安全操作比线程不安全操作的效率要低一点,也就是运行速度慢一点,所以使用StringBuffer比使用StringBuilder其运行要慢一点。 (对于线程我们现在还没学之后深入学习再去讲解)
关于String习题
习题总共有三题,大家可以做一下,链接放在下面了,这些题目都很简单,我就不多讲了,直接上代码,大家看下代码应该都能看懂:
求第一个只出现一次的字符
. - 力扣(LeetCode)
class Solution { public int firstUniqChar(String s) { int[] count = new int[256]; // 统计每个字符出现的次数 for(int i = 0; i < s.length(); ++i){ count[s.charAt(i)]++; } // 找第一个只出现一次的字符 for(int i = 0; i < s.length(); ++i){ if(1 == count[s.charAt(i)]){ return i; } } return -1; }}
求字符串最后一个单词的长度
字符串最后一个单词的长度_牛客题霸_牛客网
import java.util.Scanner; public class Main{ public static void main(String[] args){ // 循环输入 Scanner sc = new Scanner(System.in); while(sc.hasNext()){ // 获取一行单词 String s = sc.nextLine(); // 1. 找到最后一个空格 // 2. 获取最后一个单词:从最后一个空格+1位置开始,一直截取到末尾 // 3. 打印最后一个单词长度 int len = s.substring(s.lastIndexOf(' ')+1).length(); System.out.println(len); } }}
检测字符串是否为回文串
. - 力扣(LeetCode)
class Solution { public static boolean isValidChar(char ch){ if((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')){ return true; } return false; } public boolean isPalindrome(String s) { // 将大小写统一起来 s = s.toLowerCase(); int left = 0, right = s.length()-1; while(left < right){ // 1. 从左侧找到一个有效的字符 while(left < right && !isValidChar(s.charAt(left))){ left++; } // 2. 从右侧找一个有效的字符 while(left < right && !isValidChar(s.charAt(right))){ right--; } if(s.charAt(left) != s.charAt(right)){ return false; }else{ left++; right--; } } return true; }}
这里多说一点,之所以在左侧和右侧找一个有效字符时还要加上left<rightt这条件,是因为当字符串全为非字母数字字符时,我们没有该条件会导致数组越界而报错。当我们有了该条件就能解决该情况,并且特殊情况下的结果和实际情况一模一样。(如不存在字母数字字符情况)
总结
所以我们讲的String类就完结啦,现在我们讲的主要还是如何去使用String类,等到数据结构时我们还会提及String讲其更深层的内容.
还希望各位大佬们能给个三连,点点关注,点点赞,发发评论呀,感谢各位大佬~❤️❤️??????!