首页 > 编程语言 >java中String、StringBuffer和StringBuilder的区别(简单介绍)

java中String、StringBuffer和StringBuilder的区别(简单介绍)

时间:2023-11-13 13:33:38浏览次数:37  
标签:java String StringBuffer System 线程 str StringBuilder

简单介绍

java中用于处理字符串常用的有三个类:

1、java.lang.String

2、java.lang.StringBuffer

3、java.lang.StrungBuilder

三者共同之处:都是final类,不允许被继承,主要是从性能和安全性上考虑的,因为这几个类都是经常被使用着,且考虑到防止其中的参数被参数修改影响到其他的应用。

StringBuffer是线程安全,可以不需要额外的同步用于多线程中;

StringBuilder是非同步,运行于多线程中就需要使用着单独同步处理,但是速度就比StringBuffer快多了;

StringBuffer与StringBuilder两者共同之处:可以通过append、indert进行字符串的操作。

String实现了三个接口:Serializable、Comparable<String>、CarSequence

StringBuilder只实现了两个接口Serializable、CharSequence,相比之下String的实例可以通过compareTo方法进行比较,其他两个不可以。

 

这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。

  1、首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String

  String最慢的原因:String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。以下面一段代码为例:

1 String str="abc";
2 System.out.println(str);
3 str=str+"de";
4 System.out.println(str);

运行这段代码会发现先输出“abc”,然后又输出“abcde”,好像是str这个对象被更改了,其实,这只是一种假象罢了,JVM对于这几行代码是这样处理的,首先创建一个String对象str,并把“abc”赋值给str,然后在第三行中,其实JVM又创建了一个新的对象也名为str,然后再把原来的str的值和“de”加起来再赋值给新的str,而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了,所以,str实际上并没有被更改,也就是前面说的String对象一旦创建之后就不可更改了。所以,Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。

而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。

另外,有时候我们会这样对字符串进行赋值

1 String str="abc"+"de";
2 StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");
3 System.out.println(str);
4 System.out.println(stringBuilder.toString());

这样输出结果也是“abcde”和“abcde”,但是String的速度却比StringBuilder的反应速度要快很多,这是因为第1行中的操作和String str="abcde";是完全一样的,所以会很快,而如果写成下面这种形式

1 String str1="abc";
2 String str2="de";
3 String str=str1+str2;

那么JVM就会像上面说的那样,不断的创建、回收对象来进行这个操作了。速度就会很慢。

复制代码
  public static void main(String[] args) {
        long a=new Date().getTime();
        String cc="";
        int n=10000;
        for (int i = 0; i < n; i++) {
            cc+="."+i;
        }
        System.out.println("String使用的时间"+(System.currentTimeMillis()-a)/1000.0+"s");
        long s1=System.currentTimeMillis();
        StringBuilder sb=new StringBuilder();
        for (int i = 0; i < n; i++) {
            sb.append("."+i);
        }
        System.out.println("StringBuilder使用的时间"+(System.currentTimeMillis()-s1)/1000.0+"s");
        long s2=System.currentTimeMillis();
        StringBuffer sbf=new StringBuffer();
        for (int i = 0; i < n; i++) {
            sbf.append("."+i);
        }
        System.out.println("StringBuffer使用的时间"+(System.currentTimeMillis()-s2)/1000.0+"s");
    }
复制代码

 

 

  2. 再来说线程安全

  在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的

  如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

(一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞)

  3. 总结一下 

   String:适用于少量的字符串操作的情况

   StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

   StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

标签:java,String,StringBuffer,System,线程,str,StringBuilder
From: https://www.cnblogs.com/zhangsai/p/17828908.html

相关文章

  • java(StringBuilder)练习
    需求:键盘录入一个九位数以下的数字将该数字各数字变为罗马数字。importjava.util.Scanner;publicclassBoke{publicstaticvoidmain(String[]args){ScannerSc=newScanner(System.in);Stringx;while(true){System.out.......
  • String.fromCharCode 函数如何在 html 输入字段中用于移动键盘
    String.fromCharCode函数用于将Unicode编码转换为对应的字符。在HTML输入字段中,您可以使用JavaScript和String.fromCharCode函数来移动键盘。以下是一个简单的示例:首先,创建一个HTML文件,包含一个输入框和一个按钮:<!DOCTYPEhtml><htmllang="en"><head><metacharse......
  • Java项目配置Maven依赖时不知需要的最低jdk版本?(报错java: 错误: 无效的目标发行版:17)
    1.问题在配置SpringBoot项目依赖时,使用了最新的spring-boot-starter-parent3.1.5,但是出现了java:错误:无效的目标发行版:17的报错2.解决经过查阅资料后得知是jdk版本不匹配导致的错误,那我们如何得知相应依赖需要的最低版本需求,并进行配置呢?Maven依赖仓库1.登陆进这个网站后......
  • JavaScript 基础知识
    运营商 运算符对数据进行操作。它们有多种形式,包括算术运算符(+、-、*、/)、比较运算符(==、!=、<、>)和逻辑运算符(&&、||、!) 控制流语句 控制流语句根据特定条件控制代码块的执行顺序。它们包括if-else语句、switch语句和循环。数组 数组是数据项的有序集合。它们允许您......
  • Java的设计模式之原型模式
    在某些情况下,需要创建对象的副本,但是复制一个对象的成本可能很高,或者希望避免与对象的具体类耦合。例如,当创建对象的过程较为复杂,或者对象包含大量共享的状态时,使用常规的创建方法可能会导致性能下降。原型模式的解决方案是通过复制现有对象来创建新对象,而不是从头开始构建。这允许......
  • JAVA
    Java是一种具有简单的、面向对象的、分布式的、解释型的、健壮的、安全的、体系结构中立的、可移植的、高性能的、多线程的、动态的语言。JVE是虚拟机  JRE是JAVA的运行环境  JDK是程序开发工具包 写一个类的模版(简单称呼编写Java源代码)publicclass类名{  publ......
  • java中类名一定要和java文件名一致吗?
    原文链接:https://blog.csdn.net/qq_42449963/article/details/106199732 结论:首先java中类名不一定要和java文件名一致,是否一致需要分情况,其次java中可以有多个类,但是最多只有一个类的类名和文件名相同,如果一个类被public修饰,那该类的类名必须和文件名相同,并且一个java文件中......
  • Java异常
     异常异常是程序执行时,出现的意想不到的情况,导致你的程序会无法正常运行。异常类的种类(1)java.lang.Throwable类是Java程序执行过程中发生的异常时间对应类的父类(2)Throwable可分为两类:Error(错误)和Exception(异常)①Error:Java虚拟机无法解决的严重问题。比如JVM系统内......
  • java引入jep实现四则运算包含负数且规范两位小数
    1.在pom中引入依赖<!--四则运算--><dependency><groupId>jep</groupId><artifactId>jep</artifactId><version>2.24</version></dependency>2.调用实现计算 publics......
  • 《实战Java高并发程序》——第2章 Java并行程序基础
    进程和线程简单的话来说,在Windows中看到的后缀为.exe的文件都是程序。不过程序是"死"的、静态的。当双击这个.exe文件的时候,这个.exe文件中的执行就会被加载,你就能得到一个有关这个程序的进程。进程是"活"的,或者说是正在被执行的。进程中可以容纳若干线程。那进程和线程之间究......