java面试题----String、StringBuffer、StringBudder区别
面试题1 - 什么情况下用+运算符进行字符串连接比调用StringBuffer/StringBuilder对象的append方法连接字符串性能更好?
面试题2 - 请说出下面程序的输出。
class StringEqualTest {
public static void main(String[] args) {
String s1 = "Programming";
String s2 = new String("Programming");
String s3 = "Program";
String s4 = "ming";
String s5 = "Program" + "ming";
String s6 = s3 + s4;
System.out.println(s1 == s2);
System.out.println(s1 == s5);
System.out.println(s1 == s6);
System.out.println(s1 == s6.intern());
System.out.println(s2 == s2.intern());
}
}
返回值:
false
true
false
true
false
今天在看面试题的时候注意到一个String的intern()方法,平常没用过,只是见过这个方法,也没去仔细看过这个方法。所以今天看了一下。个人觉得给String类中加入这个方法可能是为了提升一点点性能,因为从常量池取数据比从堆里面去数据要快一些。(个人感觉)
API上的那几句关于这个方法,其实总结一句就是调用这个方法之后把字符串对象加入常量池中,常量池我们都知道他是存在于方法区的,他是方法区的一部分,而方法区是线程共享的,所以常量池也就是线程共享的,但是他并不是线程不安全的,他其实是线程安全的,他仅仅是让有相同值的引用指向同一个位置而已,如果引用值变化了,但是常量池中没有新的值,那么就会新开辟一个常量结果来交给新的引用,而并非像线程不同步那样,针对同一个对象,new出来的字符串和直接赋值给变量的字符串存放的位置是不一样的,前者是在堆里面,而后者在常量池里面,另外,在做字符串拼接操作,也就是字符串相"+"的时候,得出的结果是存在在常量池或者堆里面,这个是根据情况不同不一定的,我写了几行代码测试了一下。
先上结果:
1.直接定义字符串变量的时候赋值,如果表达式右边只有字符串常量,那么就是把变量存放在常量池里面。
2.new出来的字符串是存放在堆里面。
3.对字符串进行拼接操作,也就是做"+"运算的时候,分2中情况:
i.表达式右边是纯字符串常量,那么存放在栈里面。
ii.表达式右边如果存在字符串引用,也就是字符串对象的句柄,那么就存放在堆里面。

String str1 = "aaa";
String str2 = "bbb";
String str3 = "aaabbb";
String str4 = str1 + str2;
String str5 = "aaa" + "bbb";
System.out.println(str3 == str4); // false
System.out.println(str3 == str4.intern()); // true
System.out.println(str3 == str5);// true

结果:str1、str2、str3、str5都是存在于常量池,str4由于表达式右半边有引用类型,所以str4存在于堆内存,而str5表达式右边没有引用类型,是纯字符串常量,就存放在了常量池里面。其实Integer这种包装类型的-128 ~ +127也是存放在常量池里面,比如Integer i1 = 10;Integer i2 = 10; i1 == i2结果是true,估计也是为了性能优化。
学习了String类和StringBuffer类,现在从三分面来总结一下String、StringBuffer、StringBudder三者的区别:
- 是否可变:
String:底层利用字符数组保存字符串常量,是不可变的,因为String类的原码中有:private final char value[];因为有final修饰,所以String类的对象是不可改变的。所以每次修String对象的值时,实际上是生成了一个新的对象,而指针指向了新的String对象;
StringBuffer和StringBudder底层是利用字符数组保存字符串变量的,在jdk1.7中它们都继承了AbstractStringBuilder类,而在AbstractStringBuilder类中有char[] value;,所以这两者对象是可变的;
执行速度:一般情况StringBudder > StringBuffer > String
String:因为String对象是不可变的,所以每次修String对象的时候,实际上是生成了一个新的对象,而指针指向了新的String对象;所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
StringBuffer:而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。
但是有特殊情况: String str = “abc” + “def”;StringBuffer Sb = new
StringBuilder(“abc”).append(“
def”);这时这种情况下:String的速度就要比StringBuffer的速度要快,因为这时jvm认为String str = “abc”
+ “def”;其实是:String str =
“abcdef”;所以速度当然很快,这里说的是当String保存的字符串中有其他String的字符串时,速度就会变慢。是否线程安全:
String: String中的对象是不可变的,也就可以理解为常量,显然线程安全。
StringBuffer:是线程安全的,因为对方法加了同步锁或者对调用的方法加了同步锁,部分方法原码如下:
public synchronized int length() {
return count;
}
public synchronized int capacity() {
return value.length;
}
public synchronized void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity);
}
}
StringBudder:并没有对方法进行加同步锁,所以是非线程安全的。部分方法原码如下:
private StringBuilder append(StringBuilder sb) {
if (sb == null)
return append("null");
int len = sb.length();
int newcount = count + len;
if (newcount > value.length)
expandCapacity(newcount);
sb.getChars(0, len, value, count);
count = newcount;
return this;
}
public StringBuilder delete(int start, int end) {
super.delete(start, end);
return this;
}
- 对三者的使用意见:
1.如果要操作少量的数据用: String
2.单线程操作字符串缓冲区 下操作大量数据 :StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 : StringBuffer
java面试题----String、StringBuffer、StringBudder区别的更多相关文章
- Java学习之String StringBuffer StringBuilder区别
1.String:对象长度是不可变的,是线程安全. 2.StringBuffer:对象长度是可变的,是线程安全. 3.StringBuilder:对象长度是可变,不是线程安全.
- 在JAVA中,String,Stringbuffer,StringBuilder 的区别
首先是,String,StringBuffer的区别 两者的主要却别有两方面,第一是线程安全方面,第二是效率方面 线程安全方面: String 不是线程安全的,这意味着在不同线程共享一个String ...
- 【Java基础】String StringBuffer StringBuilder
String String是不可变的 我们都知道String不是基本数据类型,而是一个对象,并且是final类型的,不可变的.(public final class String) 查看以下代码: S ...
- String,StringBuffer,StringBudilder区别--2019-04-13
String,StringBuffer,StringBudilder区别: 1String 是字符串常量,创建内容不可以变, final修饰意味着String类型不能被继承,减少被修改的可能,从而最大 ...
- Android/Java 中的 String, StringBuffer, StringBuilder的区别和使用
Android 中的 String, StringBuffer 和 StringBuilder 是移动手机开发中经常使用到的字符串类.做为基础知识是必须要理解的,这里做一些总结. A.区别 可以从以下 ...
- String,StringBuffer,StringBuilder区别
String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...
- Java学习笔记--String StringBuffer StringBuilder
String StringBuffer StringBuilder String http://docs.oracle.com/javase/7/docs/api/ 中文: http://www.cn ...
- 浅谈 Java 字符串(String, StringBuffer, StringBuilder)
我们先要记住三者的特征: String 字符串常量 StringBuffer 字符串变量(线程安全) StringBuilder 字符串变量(非线程安全) 一.定义 查看 API 会发现,String ...
- 转:String StringBuffer StringBuilder区别
转自:http://www.iteye.com/topic/522167 作者:每次上网冲杯Java时,都能看到关于String无休无止的争论.还是觉得有必要让这个讨厌又很可爱的String美眉,赤裸 ...
- 重温java中的String,StringBuffer,StringBuilder类
不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...
随机推荐
- Kibana6.x.x源码分析--Error: $injector:nomod Module Unavailable
首先我的依赖注入写法如下: 由于是新手,比对着Kinaba中已有的插件,进行摸索开发,但运行代码后,发现在注册依赖的时候报错了.如下截图所示: 然后根据提示:http://errors.angular ...
- 洛谷 P2147 [SDOI2008]洞穴勘测 (线段树分治)
题目链接 题解 早就想写线段树分治的题了. 对于每条边,它存在于一段时间 我们按时间来搞 我们可把一条边看做一条线段 我们可以模拟线段树操作,不断分治下去 把覆盖\(l-r\)这段时间的线段筛选出来, ...
- UVA - 11029 输出前三位
题意:给定\(a\)和\(n\),输出\(a^n\)的前三位和后三位 后三位快速幂 \(log_{10}(a^n)=n*log_{10}(a)=n*log_{10}(x*y),y<10,x mo ...
- date +%F时间日期
date +%Y -%m-%d 年月日 date +%T 显示时间 HMS几点几分几秒 -%H 为小时 %w 周几 date -d “-1day” 一天之前 date ...
- layui 数据返回但是table表格未渲染出来的问题
最近蜂鸟速驾项目用layui框架,table进行表格渲染 控制台打印发现有数据,但是table.render渲染不出来,后来发现是数据已经返回但是页面元素未加载完成的缘故,用setTimeout定时器 ...
- rewrite 功能
一, rewrite 地址重写与地址转发 区别: 1,地址转发后客户端浏览器地址栏中的地址时不会改变的;而地址重写的话客户端浏览器地址栏会改变为服务器确定的地址 2, 在一次地址转发过程中,只产生一次 ...
- DP Intro - Tree DP Examples
因为上次比赛sb地把一道树形dp当费用流做了,受了点刺激,用一天时间稍微搞一下树形DP,今后再好好搞一下) 基于背包原理的树形DP poj 1947 Rebuilding Roads 题意:给你一棵树 ...
- Unity GetComponentsInChildren<T>(true);
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GetCompo ...
- opengl键盘回调函数不能获取Ctrl+c的问题
我要令窗口在按下 Ctrl+c 之后关闭. 关键代码如下: /* 这段代码位于键盘回调函数中 */ if ((glutGetModifiers() == GLUT_ACTIVE_CTRL) & ...
- 15019:Only the instance admin may alter the PermSize attribute
15019:Only the instance admin may alter the PermSize attribute TimesTen提示空间不足,增加空间重启后提示15019:Only th ...