深刻理解Java中的String、StringBuffer和StringBuilder的差别
声明:本博客为原创博客,未经同意。不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(链接为http://blog.csdn.net/bettarwang/article/details/26412497),看代码和提问、讨论都更方便。
首先简单地来梳理一下Java中String、StringBuffer和StringBuilder各自的含义。
1.String类
首先。它是线程安全的,即能够用于多线程编程中。
其次,String类的对象是不可变的,即在定义时就确定了,类似String str="Hello";str+="Java";的语句事实上是生成了新的对象,仅仅是我们未察觉到而已。可是注意在大量的字符串新建对象时消耗就非常可观。这时必须考虑採用StringBuffer或StringBuilder,否则会极大地减少程序的效率。
2.StringBuffer类:
首先,它也是线程安全的。
其次,它是可变类,对它指向的字符串的操作都不会产生新的对象。 每一个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自己主动添加容量。因而它的效率要比String高。
StringBuffer
类最经常使用的两个方法是 append 和 insert 方法,StringBuffer已经重载了这些方法,以接受随意类型的数据,所以小伙伴们。如果strBuffer是StringBuffer的对象。那么像strBuffer.append(3.14f);strBuffer.append(true);这种语句都是全然合法的。
3.StringBuilder类:
首先,它不是线程安全的。即仅仅能用于单线程编程中。
其次。它跟StringBuffer类似,即其对象也是一个可变的字符序列。可是要注意的是它以下几种构造方法:
StringBuilder():创建一个容量为16的StringBuilder对象。
StringBuilder(int
capacity):创建一个容量为capacity的StringBuilder对象;
StringBuilder(String
s):创建一个包括s的StringBuilder对象。同一时候末尾加入16个空元素。
StringBuilder(CharSequence
cs):创建一个包括cs的StringBuilder对象,末尾附加16个空元素;
综上可知。在线程同步方面。String和StringBuffer是线程安全的,而StringBuilder不是线程安全的;在运行效率上,StringBuilder>StringBuffer>String,因而在须要大量的进行字符串操作的单线程场合,应该昼使用StringBuilder以提高效率,在大量进行字符串操作的多线程情形,StringBuffer无疑是最佳的选择。而对于少量的字符串操作的单线程或多线程情形下,使用String则更为简单、方便。
上面对这三个类进行了一下梳理,但这仅仅是基础知识,根本谈不上深刻理解。取这么一个题目不是想哗众取宠。以下就開始结合我自己的一些经历谈一下自己的理解。
我们都知道,String类的对象是不可变的。可是又考虑到Java中”一切皆引用“,以为在函数中传String引用能够实现值的改变。因而经常犯以下这种错误:
import java.util.*;
import java.io.*; public class StringTest
{
private static void treatString(String str)
{
if(str.contains("hello"))
{
str="hello java";
}
else
{
str="enjoy java";
}
} public static void main(String[]args)
{
String str1="hello world";
String str2="study java";
treatString(str1);
treatString(str2); System.out.println(str1);
System.out.println(str2);
}
}
输出结果例如以下图所看到的:
本来期望传递引用从而改变字符串str1和str2的值,可是从输出结果看字符串的值却是根本没有被改变,这是为什么呢?
原来确实传递的也是引用。可是与一般的对象不同,treatString(String)函数并没有对str指向的对象进行改动(或者说并没有在str指向的内存地址上进行改动)。而是新建了一个String对象。可是这个新建的对象却是仅仅有形參指向它,实參并没有指向它。实际上整个过程中实參str都始终还是指向最開始那个对象。所以不难理解为什么会有这种输出结果。
那么假设想要获得一般对象传递引用的效果该怎么办?
非常easy,第一种方法,也是我个人比較推荐的方法,就是返回值String而不是void,即将上面的代码改动为:
import java.util.*;
import java.io.*; public class StringTest
{
//private static void treatString(String str)
private static String treatString(String str)
{
if(str.contains("hello"))
{
str="hello java";
}
else
{
str="enjoy java";
} return str;
} public static void main(String[]args)
{
String str1="hello world";
String str2="study java";
str1=treatString(str1);
str2=treatString(str2); System.out.println(str1);
System.out.println(str2);
}
}
此时输出结果例如以下图所看到的:
显然。此时已经达到了我们预期的目的。
到了这里,我再结合自己的还有一个经历,就是一開始对String.replace(oldChar,newChar);这个函数不熟悉。以为仅仅要调用它就能够实现str的改变(即以为直接str.replace(oldChar,newChar);就能实现str的改变),实际上要利用它的返回值才干改变str,即str=str.replace(oldChar,newChar);才是正确的做法。
另外一种方法,当然就是利用StringBuffer和StringBuilder喽,由于它们是对象可变的嘛。
详细样例到后面再追加。今天先写到这里吧。
晚安啦,小伙伴们!
深刻理解Java中的String、StringBuffer和StringBuilder的差别的更多相关文章
- 深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因
声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/det ...
- Android/Java 中的 String, StringBuffer, StringBuilder的区别和使用
Android 中的 String, StringBuffer 和 StringBuilder 是移动手机开发中经常使用到的字符串类.做为基础知识是必须要理解的,这里做一些总结. A.区别 可以从以下 ...
- 深入理解Java中的String
一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...
- 【转】深入理解Java中的String
原文链接:http://www.cnblogs.com/xiaoxi/p/6036701.html 一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码 ...
- Java中String,StringBuffer与StringBuilder的差别
String 字符串常量: StringBuffer 字符串变量〈缓冲区〉(线程安全): StringBuilder 字符串变量〈缓冲区〉(非线程安全): 简要的说, String 类型和 Strin ...
- 重温java中的String,StringBuffer,StringBuilder类
不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...
- JDK学习---深入理解java中的String
本文参考资料: 1.<深入理解jvm虚拟机> 2.<大话数据结构>.<大话设计模式> 3.http://www.cnblogs.com/ITtangtang/p/3 ...
- 在JAVA中,String,Stringbuffer,StringBuilder 的区别
首先是,String,StringBuffer的区别 两者的主要却别有两方面,第一是线程安全方面,第二是效率方面 线程安全方面: String 不是线程安全的,这意味着在不同线程共享一个String ...
- 深刻理解Java中形參与实參,引用与对象的关系
声明:本博客为原创博客,未经同意.不得转载! 原文链接为http://blog.csdn.net/bettarwang/article/details/30989755 我们都知道.在Java中,除了 ...
随机推荐
- BZOJ-3732 Network 图论 最小生成树 倍增
题面 题意:给你N个点,M条边的无向图 (N<=15000,M<=30000)第j条边的长度为 dj (1<=dj<=1e9),然后K个询问 (1<=K<=2000 ...
- colab使用谷歌云中的文件
colab使用谷歌云中文件 无法一劳永逸 Google Colab最大的不足就是使用虚拟机,这意味着我们自行安装的库虚拟机重启之后,就会被复原,比如keras,数据无法持久化.为了能够持久保存数据,我 ...
- BZOJ 4403 2982 Lucas定理模板
思路: Lucas定理的模板题.. 4403 //By SiriusRen #include <cstdio> using namespace std; ; #define int lon ...
- Windows Server2008上安装VS2008出错及解决办法
作者:朱金灿 来源:http://blog.csdn.net/clever101 win server 2008安装vs2008后报错,如下图: 然后到网上找了一种解决办法: (1)打开服务器管理器 ...
- Functor、Applicative 和 Monad(重要)
Functor.Applicative 和 Monad Posted by 雷纯锋Nov 8th, 2015 10:53 am Functor.Applicative 和 Monad 是函数式编程语言 ...
- MyBatis 基础入门
MyBatis 是一个半自动化的持久层的框架,能让开发者专注SQL本身 JDBC 连接数据库的硬编码问题,通过config,mapper配置文件解决 Mybatis开发需要关注的文件 l POJO类( ...
- SQL数据查询2
USE h CREATE TABLE zy1( empno INT, ename ), job ), mgr INT, hiredate DATE, sal DOUBLE, COOM DOUBLE, ...
- js给文本添加行号
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Nginx负载均衡health_check分析
在Nginx负载均衡中,我们很难保证说每一台应用服务器都能一直正常的运行下去.但是我们可以通过设置Nginx来检测这些应用服务器,检测这些服务器当中不能访问的. Nginx的检测方式分为两种,一种是被 ...
- python中的网页标签等字符处理
# -*- coding: utf-8-*- import re ##过滤HTML中的标签 #将HTML中标签等信息去掉 #@param htmlstr HTML字符串. def filter_tag ...