Java 中StringBuffer与StringBuilder区别(转)及String类的一些基本操作代码
2015-10-10 15:30
477 查看
String 字符串常量
StringBuffer 字符串变量(线程安全) 多个线程访问时,不会产生问题(Synchronized)
StringBuilder 字符串变量(非线程安全) 多个线程访问时可能会产生问题
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
String S1 = “This is only a” + “ simple” + “test”; 其实就是:
String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
这时候 JVM 会规规矩矩的按照原来的方式去做
在大部分情况下 StringBuffer > String
StringBuffer
Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。
在大部分情况下 StringBuilder > StringBuffer
java.lang.StringBuilde
java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
(转自 http://blog.csdn.net/rmn190/article/details/1492013)
String类操作代码如下
StringBuffer 字符串变量(线程安全) 多个线程访问时,不会产生问题(Synchronized)
StringBuilder 字符串变量(非线程安全) 多个线程访问时可能会产生问题
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
String S1 = “This is only a” + “ simple” + “test”; 其实就是:
String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
这时候 JVM 会规规矩矩的按照原来的方式去做
在大部分情况下 StringBuffer > String
StringBuffer
Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。
在大部分情况下 StringBuilder > StringBuffer
java.lang.StringBuilde
java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
(转自 http://blog.csdn.net/rmn190/article/details/1492013)
String类操作代码如下
import java.util.Date; public class Test14 { public static void main(String[] args){ char[] charA = {'a','b','c','在'}; String strA = new String(charA); System.out.println(strA); System.out.println(1 + 2 + strA); //与字符串直接相连,加号为字符串连接符,不与字符串连接的依然为算术运算符 //输出结果为 3abc int len = strA.length(); System.out.println(len);//length()方法输出的是字符个数,含有汉字 //4 System.out.println('d' + "a");//字符直接与字符串相连 加号为字符串连接符 //da System.out.println('a' + 'd' + "a");//字符不直接与字符串相连 前+为算术运算 //197a System.out.println('a' + 'd');//字符不与与字符串相连 +为算术运算 //197 System.out.println(1 + 2 + 's');//字符型会自动转换为int型的编码相加 //118 System.out.println(strA.indexOf("a"));//0 System.out.println(strA.indexOf("d"));//找不到返回-1 System.out.println(strA.indexOf('a'));//0 前查找 如果为字符会自动转化成int型 然后匹配字符串中的字符 System.out.println(strA.lastIndexOf("a"));//0 后查找 System.out.println(strA.lastIndexOf(""));//空字符串输出的其实是字符串长度 4 System.out.println(strA.charAt(3));//返回指定索引位置的字符 System.out.println(strA.substring(2));//返回指定索引位置以后的字符串 c在 System.out.println(strA.substring(2,3));//返回指定索引位置到终索引(不含)的字符串 c System.out.println(strA.trim());//忽略前空格和后空格 System.out.println(strA.replace("a", "A"));//替换 System.out.println(strA.startsWith("a"));// 前匹配 true System.out.println(strA.endsWith("b"));//后匹配 false String strB = new String("abc"); String strC = new String("abc"); String strD = "abc"; String strE = "abc"; System.out.println(strB == strC);//false new是在堆内存重新创建"abc" 引用地址会不一样 System.out.println(strB == strD);//false strD指向String常量池,与strB指向不一样 System.out.println(strE == strD);//true 都指向String常量池的同一"abc" System.out.println(strB.equals(strC));//true 只要内容相等就相等(其实内容都在String常量池中) //同时含有忽略大小写的比较 equalsIgnoreCase(); strD = "d"; strE = "a"; String strF = "h"; System.out.println(strD.compareTo(strE));//3 正数 d在a之后第三个位置 System.out.println(strD.compareTo(strF));//-4 正数 d在h之前第4个位置 System.out.println(strD.toUpperCase());//D //转换成小写的 toLowerCase(); Date date = new Date(); System.out.println(String.format("%te", date));//返回时间的天数 //format()方法是String的静态方法 需要了解常用类型的格式化参数 String strG = new String("a,b c,d"); for (String str : strG.split(",| ")) System.out.println(str);//字符串的分割,返回字符串 //split方法参数是字符串,可以用"|"分隔多个分隔符 //a b c d for (String str : strG.split(",| ",2))//方法中可限制分割次数 这就是分两次 System.out.println(str);//结果 a b c,d两个字符串数组元素 //StringBuilder类的一些基本操作 StringBuilder strBuilder = new StringBuilder("Hello"); System.out.println(strBuilder); strBuilder.append("World");//末尾附加 System.out.println(strBuilder); strBuilder.insert(5, "Java");//指定索引位置添加 System.out.println(strBuilder); strBuilder.delete(5, 9);//不包括末尾索引 System.out.println(strBuilder); } }
相关文章推荐
- URAL 1910 Titan Ruins: Hidden Entrance
- UILable , Button
- request_irq() | 注册中断服务参考
- read PSE TPS2384 POE Firmware Guide
- 转:QT如何将.UI文件转成.h或.cpp文件
- UIView 的 属 性
- UILabel 属性祥记
- UIImage编码成Base64后上传,服务器端解码出错
- I.MX6 Manufacturing Tool V2 (MFGTool2) Update Command List (UCL) User Guide translate
- UITableView绑定不同的cell 的 ID 写法
- ios UITextField 设置默认提示
- hdu 5288 OO’s Sequence
- CEGUI-----动画
- 【Java GUI】Java GUI基金会
- 怪异模式(Quirks Mode)对 HTML 页面的影响
- apue第三章文件I/O
- Invalid ADAPTORNAME specified. Type 'imaqhwinfo' for a list of available ADAPTORNAMEs. Image acquisi
- UIMenuController 和 UIMenuItem 的使用
- IOS 自定义 UISegmentedControl
- IOS控制UITextField输入字数