JAVA-StringBuilder和StringBuffer

embedded/2024/9/25 23:13:54/

一、认识String类

1.认识

String在Java中是字符串类型,但与其他类型不同。它是一个类,可以创建对象的类。与int、char等自待类型有些许不同。但它仍然是java提供的一种类型。

 类中有4个属性,这里主要认识一下value属性。它是实际存放字符串的引用。那么我们来看一下源码:

2.String的不可变性

可以看到value数组被final修饰,那么他里面的值是不可以变的。但是java又提供了非常多对String类操作的方法,对里面的value数组进行更改。但是实际上,他都是创建一个新的String类对其进行操作,并返回新的String类。

这样会有一个非常大的问题,有这样一个代码:

java">public static void main(String[] args) {String array = "a";for (int i = 0; i < 1000; i++) {//他在这里会不停的发生创建新的对象//并进行拼接//然后再返回新的对象array += i;}System.out.println(array);}

这会大大提升时间空间复杂度

那么以后在使用字符串并且,对字符串进行大量操作,或者不想创建新的String类的时候可以使用StringBuilder和StringBuffer

二、StringBuilder和StringBuffer

1.StringBuilder和Strinig的区别

这里使用StringBuilder进行对比

正常使用StirngBuilder进行拼接:

java">public static void main(String[] args) {StringBuilder s = new StringBuilder("a");for (int i = 0; i < 1000; i++) {s.append(i);//想当与String的+=}System.out.println(s.toString());
}

用StringBuilder模拟Stirng进行拼接:

java">    public static void main(String[] args) {StringBuilder s1 = new StringBuilder("a");for (int i = 0; i < 1000; i++) {StringBuilder tmp = new StringBuilder("");tmp = s1.append(i);}System.out.println(s1.toString());}

创建类本来就是一个复杂的过程,如果使用String他会创建1000次,那速度肯定是大大降低。

StringBuffer也是跟StringBuilder相同的操作,那StringBuilder和StringBuffer有哪些区别呢?这也是面试常考题

2.String、StringBuffer、StringBuilder的区别

  1. String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
  2. StringBuffer与StringBuilder大部分功能是相似的
  3. StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

这个第3项给大家解释一下:想要真正了解这个东西需要多线程的理解,这里给大家简单解释一下。

一边看图一边看我解释:

厕所可以看作是一种资源吧

StringBuffer更像家里的厕所,是有锁的。你在上厕所(你在使用资源)别人是进不来的。

StirngBuilder更像是公共场所,没有锁想进来就进来,那肯定没有家里的厕所有安全感。

所以:StringBuffer是安全的,StringBuilder是不安全的。但目前我们写的程序都是单线程的

3.String、StringBuffer、StringBuilder的运行时间区别

使用System.currentTimeMillis()方法可以获取当前时间的一个毫秒数。

用 当前时间-指向前时间 = 时间差

java">public static void main(String[] args) {long start = System.currentTimeMillis();//获得当前时间毫秒数String s = "";for(int i = 0; i < 100000; ++i){s += i;}long end = System.currentTimeMillis();System.out.println("String" + (end - start));start = System.currentTimeMillis();StringBuffer sbf = new StringBuffer("");for(int i = 0; i < 100000; ++i){sbf.append(i);}end = System.currentTimeMillis();System.out.println("StringBuffer" + (end - start));start = System.currentTimeMillis();StringBuilder sbd = new StringBuilder();for(int i = 0; i < 100000; ++i){sbd.append(i);}end = System.currentTimeMillis();System.out.println("StringBuilder" + (end - start));}

 结果:

可以看到String与StirngBuilder和StringBuffer的区别是巨大的。但这里并没有体现出StirngBuilder和StringBuffer之间的差距,可能是现在做了优化。不过在不涉及多线程的时候推荐使用StirngBuilder要更快一点。

三、StringBuilder和StringBuffer的常用方法

想要了解String常用方法的可以看我这篇博客:String类和String类常用方法-CSDN博客

1. StringBuff append(String str) 拼接字符串

StringBuff append(String str)在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、 double、float、int、long、Object、String、StringBuff的变量
java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("");int[] arr = new int[]{1,2,3,4,5};stringBuilder.append("a");stringBuilder.append(1);stringBuilder.append(1.5);stringBuilder.append('c');for (int a: arr) {stringBuilder.append(a);}System.out.println(stringBuilder.toString());//a11.5c12345
}

2.char charAt(int index) 获取index位置的字符

java">  public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("hello");System.out.println(stringBuilder.charAt(0));//hSystem.out.println(stringBuilder.charAt(-1));//异常System.out.println(stringBuilder.charAt(stringBuilder.length()));//异常}

3.int length() 获取字符串的长度

java"> public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("hello");System.out.println(stringBuilder.length());//5}

4.int capacity() 获取底层保存字符串空间总的大小

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("hello");System.out.println(stringBuilder.capacity());//21
}

 

5.void ensureCapacity(int mininmumCapacity) 扩容

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("hello");System.out.println(stringBuilder.capacity());//21stringBuilder.ensureCapacity(30);System.out.println(stringBuilder.capacity());//44 = 21 * 2 + 2
}

6.void setCharAt(int index, char ch) 将index位置的字符设置为ch

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("hello");stringBuilder.setCharAt(2,'a');//注意要输入char类型System.out.println(stringBuilder);//healo
}

 

indexOf函数找不到相应的字符串返回-1

7.int indexOf(String str) 返回str第一次出现的位置

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaabb");System.out.println(stringBuilder.indexOf("bb"));//2
}

8.int indexOf(String str, int fromIndex) 从fromIndex位置开始查找str第一次出现的位置

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaabb");System.out.println(stringBuilder.indexOf("bb",4));//8
}

9.int lastIndexOf(String str) 返回最后一次出现str的位置

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaabb");System.out.println(stringBuilder.lastIndexOf("aa"));//6
}

原理是从后往前找

10.int lastIndexOf(String str, int fromIndex) 从fromIndex位置开始找str最后一次出现的位置

原理是从指定位置从后向前找
java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaabbaa");System.out.println(stringBuilder.lastIndexOf("aa",5));//0System.out.println(stringBuilder.lastIndexOf("ac",5));//-1找不到
}

11.StringBuff insert(int offset, String str) 在offset位置插入:八种基类类型 & String类型 & Object类型数据

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaabbaa");//aaxxxbbccaabbaa//不会覆盖原有字符,原位置字符全部往后移System.out.println(stringBuilder.insert(2, "xxx"));//aaxxxbbccaabbaaxxx,证明可以当追加函数使用System.out.println(stringBuilder.insert(stringBuilder.length(), "xxx"));//报错//说明,要紧跟字符串末尾追加System.out.println(stringBuilder.insert(stringBuilder.length()+1, "xxx"));}

12.StringBuffer deleteCharAt(int index) 删除index位置字符

java"> public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaa");System.out.println(stringBuilder.deleteCharAt(2));//aabccaa}

13.StringBuffer delete(int start, int end) 删除[start, end)区间内的字符

注意:左开右闭[ ,)

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaa");System.out.println(stringBuilder.delete(2, 4));//aaccaa
}

 

14.StringBuffer replace(int start, int end, String str) 将[start, end)位置的字符替换为str

 注意:左开右闭[ ,)

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaa");System.out.println(stringBuilder.replace(2, 4,"xx"));//aaxxccaaSystem.out.println(stringBuilder.replace(2, stringBuilder.length() + 1,"xx"));//aaxx
}

最后一种虽然可以指向成功但绝对不建议这么写

15.String substring(int start) 从start开始一直到末尾的字符以String的方式返回 

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaa");System.out.println(stringBuilder.substring(2));//bbccaaSystem.out.println(stringBuilder.substring(stringBuilder.length()));//什么都不打印System.out.println(stringBuilder.substring(stringBuilder.length() + 1));//报错
}

16.String substring(int start,int end) 将[start, end)范围内的字符以String的方式返回

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaa");//这里不报错是因为左开,右闭System.out.println(stringBuilder.substring(2, stringBuilder.length()));//bbccaa
}

17. StringBuffer reverse() 反转字符串

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaa");//这里不报错是因为左开,右闭System.out.println(stringBuilder.reverse());//aaccbbaa
}

18.String toString() 将所有字符按照String的方式返回

java">public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("aabbccaa");//StringBuilder 以 String 类型返回System.out.println(stringBuilder.toString());//aabbccaa
}

这里要着重讲一下,原本是StringBuilder类型,要转换为String类型,就可以用toString。

 注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:

  • String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
  • StringBuilder变为String: 调用toString()方法。

 

四、面试题

1.

java">String str = new String("ab"); // 会创建多少个对象
1.会创建一个对象String str = new String("a") + new String("b"); // 会创建多少个对象
2.a创建一个对象 + b创建一个对象 + 将他们拼接起来需要一个对象 = 3个对象一共创建了4个对象

 2.String、StringBuffer、StringBuilder的区别

  • String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
  • StringBuffer与StringBuilder大部分功能是相似的 StringBuffer采用同步处理,属于线程安全操作;
  • 而StringBuilder未采用同步处理,属于线程不安全操 作

http://www.ppmy.cn/embedded/116871.html

相关文章

倒排索引(反向索引)

倒排索引&#xff08;Inverted Index&#xff09;是搜索引擎和数据库管理系统中常用的一种数据结构&#xff0c;用于快速检索文档集合中的文档。在全文搜索场景中&#xff0c;倒排索引是一种非常高效的手段&#xff0c;因为它能够快速定位到包含特定关键词的所有文档。 1、基本…

【算法】贪心+堆排序实现大根堆及标准库容器类的融合使用

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

一种单目标A*算法设计与实现

一种单目标A*算法设计与实现 作者&#xff1a;吴屏珊 最近在学习简单的单目标A*算法&#xff0c;其中在CSDN上阅读到的一篇博文给了我很大启发&#xff0c;于是在该博文的基础上&#xff0c;笔者记录了一点自己对于A*算法的体会和感悟。原文链接 目录 文章目录 一种单目标A*…

【多线程】面试高频考点!JUC常见类的详细总结,建议收藏!

&#x1f490;个人主页&#xff1a;初晴~ &#x1f4da;相关专栏&#xff1a;多线程 / javaEE初阶 JUC是“Java Util Concurrency”的缩写&#xff0c;指的是Java并发工具包&#xff0c;它位于java.util.concurrent包及其子包中。JUC包提供了大量用于构建并发应用程序的工具和…

如何在openEuler上安装和配置openGauss数据库

本文将详细介绍如何在openEuler 22.03 LTS SP1上安装和配置openGauss数据库&#xff0c;包括数据库的启动、停止、远程连接配置等关键步骤。 1、安装 使用OpenEuler-22.03-LTS-SP1-x64版本的系统&#xff0c;通过命令行安装openGauss数据库。 1.1、确保系统软件包索引是最新…

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【内核通信机制】上

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 子系统开发内核 轻量系统内核&#xff08;LiteOS-M&#xff09; 轻量系统内核&#…

[图解]静态关系和动态关系

1 00:00:01,060 --> 00:00:04,370 首先我们来看静态关系和动态关系 2 00:00:06,160 --> 00:00:10,040 我们要尽量基于静态关系来建立动态关系 3 00:00:11,740 --> 00:00:13,740 不能够在没有这个的基础上 4 00:00:14,220 --> 00:00:17,370 没有这个的情况下就胡…

Redis中String命令的基础操作

文章目录 Redis中String命令的基础操作一、引言二、String类型的基础命令1、设置与获取值1.1、SET命令1.2、GET命令 2、字符串操作2.1、APPEND命令2.2、GETRANGE命令2.3、SETRANGE命令2.4、STRLEN命令 3、数值操作3.1、INCR命令3.2、DECR命令3.3、INCRBY和DECRBY命令 三、应用场…