http://github.thinkingbar.com/how-to-use-string/
比较
一、定义
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
String、StringBuffer、StringBuilder都实现了 CharSequence接口,虽然它们都与字符串相关,但是其处理机制不同。
- String:是不可改变的量,也就是创建后就不能在修改了。
- StringBuffer:是一个可变字符串序列,它与String一样,在内存中保存的都是一个有序的字符串序列(char类型的数组),不同点是StringBuffer对象的值都是可变的。
- StringBuilder:与StringBuffer类基本相同,都是可变字符换字符串序列,不同点是StringBuffer是线程安全的,StringBuilder是线程不安全的。 在性能方面,由于String类的操作是产生新的String对象,而StringBuilder和StringBuffer只是一个字符数组的扩容而已,所以String类的操作要远慢于StringBuffer和StringBuilder。
二、使用场景
- 使用String类的场景:在字符串不经常变化的场景中可以使用String类,例如常量的声明、少量的变量运算。
- 使用StringBuffer类的场景:在频繁进行字符串运算(如拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用StringBuffer,例如XML解析、HTTP参数解析和封装。
- 使用StringBuilder类的场景:在频繁进行字符串运算(如拼接、替换、和删除等),并且运行在单线程的环境中,则可以考虑使用StringBuilder,如SQL语句的拼装、JSON封装等。
三、分析
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象。所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
四、结论
String 类是final类,不可以继承。对String类型最好的重用方式是组合 而不是继承。
String 有length()方法,数组有length属性
String s = new String(“xyz”); 创建了几个字符串对象?
两个对象,一个静态存储区“xyz”, 一个用new创建在堆上的对象。
在大部分情况下 StringBuffer > String
Java.lang.StringBuffer是线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。在程序中可将字符串缓冲区安全地用于多线程。而且在必要时可以对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append(“le”) 会使字符串缓冲区包含“startle”(累加);而 z.insert(4, “le”) 将更改字符串缓冲区,使之包含“starlet”。
在大部分情况下 StringBuilder > StringBuffer
java.lang.StringBuilder一个可变的字符序列是JAVA 5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步,所以使用场景是单线程。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的使用方法基本相同。
String
概述
String示例
public static void main(String[] args){
String str="My Name Is WingooM";
System.out.println(str);
System.out.println("获取操作.......");
//1.1获取字符串长度
int length=str.length();
System.out.println("str.length(): "+length);
//1.2获取某位置上的字符
char c =str.charAt(5);
System.out.println("str.charAt(5): "+c);
//1.3获取某字符在字符串中第一次出现的位置,区分大小写,找不到返回-1
int index = str.indexOf('T');
System.out.println("str.indexOf('T'): "+index);
int index2 = str.indexOf('M');
System.out.println("str.indexOf('M'): "+index2);
//从指定位置开始(包含该位置)获取字符在字符串中的位置
int index3=str.indexOf('m', 5);
System.out.println("str.indexOf('m',5): "+index3);
int indexstr=str.indexOf("ooM");
System.out.println("str.indexOf(\"ooM\"): "+indexstr);
//1.4从后向前查找某一字符或字符串在该字符串中第一次出现的位置
int indexstr2=str.lastIndexOf("ooM");
System.out.println("str.lastIndexOf(\"ooM\"):"+indexstr2);
System.out.println("\n2-判断...");
System.out.println(str+"\n");
//2.1判断是否包含某一字符或字符串
boolean isContain=str.contains("ooM");
System.out.println("str.contains(\"ooM\"): "+isContain);
//2.2判断字符串是否有内容
System.out.println("str.isEmpty(): "+str.isEmpty());
//2.3判断是否以指定内容开头
boolean isStart=str.startsWith("My Name ");
System.out.println("str.startsWith(\"My Name \"): "+isStart);
//2.4判断是否以指定内容结尾
boolean isEnd = str.endsWith("ingooM");
System.out.println("str.endsWith(\"WingooM\")"+isEnd);
//2.5判断字符串是否相等
System.out.println("str.equals(\"Name\"): "+str.equals("Name"));
//2.6判断字符串是否相等,并忽略大小写
System.out.println("str.equalsIgnoreCase(\"Name\"): "+str.equalsIgnoreCase("Wingoom"));
System.out.println("\n3.转换操作....");
System.out.println("初始字符串: "+str);
//3.1字符数组转换为字符串
char[] char_arr=new char[]{'M','y',' ','N','a','m','e'};
//构造函数将字符数组转为字符串
String str2= new String(char_arr);
System.out.println("\n构造函数将字符数组转为字符串:\nnew String(char_arr): "+str2);
str2=String.copyValueOf(char_arr);
System.out.println("\n函数将字符数组转为字符串:\nString.copyValueOf(char_arr): "+str2);
//表示从下标3开始,向右四个字符
String str3=String.copyValueOf(char_arr, 3, 4);
System.out.println("\n将部分字符数组转为字符串:\nString.copyValueOf(char_arr, 3, 4): "+str3);
//3.2字符串转成字符数组
char[] new_char_arr=str.toCharArray();
//数组排序
Arrays.sort(new_char_arr);
System.out.print("\n字符串转为字符数组,再排序:\nstr.toCharArray(): ");
System.out.println(new_char_arr);
//3.3字节数组转为字符串
byte[] b_arr=new byte[]{'a','b','c'};
String str4=new String(b_arr,1,2);
System.out.println("\n字节数组转为字符串:\nnew String(b_arr):"+str4);
//3.4将字符串转为字节数组
b_arr=str.getBytes();
//3.5将基本数据类型转为字符串
double dou=12.1231231;
String double_string=String.valueOf(dou);
System.out.println("将基本数据类型转为字符串: "+double_string);
System.out.println("4.替换操作....");
//将一个字符替换另一个字符,注意返回值才是替换后的字符串
System.out.println("初始字符串:"+str);
str=str.replace('M', 'W');
System.out.println(str);
//按正则表达式替换
//str.replaceFirst(regex, replacement);
System.out.println("\n5切割....");
//这里必须为双引号
String str_arr[]=str.split(" ");
System.out.println("str.split(\" \"): "+str_arr[0]+"-"+str_arr[1]+"-"+str_arr[2]);
System.out.println("\n6求子串....");
System.out.println("初始串:"+str);
//substring(begin,end)
String substring=str.substring(2, 5);
System.out.println("str.substring(3, 6): "+substring);
System.out.println("\n7大小写转换,去空格,比较....");
str=str.toUpperCase();
System.out.println("str.toUpperCase(): "+str);
str=str.toLowerCase();
System.out.println("str.toLowerCase(): "+str);
//去除两端的空白
String str_fin =" Welcome to Tutorialspoint.com ";
System.out.println(str_fin);
str_fin=str_fin.trim();
System.out.println("str.trim():\n"+str_fin);
}
输出:
My Name Is WingooM
获取操作…….
str.length(): 18
str.charAt(5): m
str.indexOf(‘T’): -1
str.indexOf(‘M’): 0
str.indexOf(‘m’,5): 5
str.indexOf(“ooM”): 15
str.lastIndexOf(“ooM”):15
2-判断…
My Name Is WingooM
str.contains(“ooM”): true
str.isEmpty(): false
str.startsWith(“My Name “): true
str.endsWith(“WingooM”)true
str.equals(“Name”): false
str.equalsIgnoreCase(“Name”): false
3.转换操作….
初始字符串: My Name Is WingooM
构造函数将字符数组转为字符串:
new String(char_arr): My Name
函数将字符数组转为字符串:
String.copyValueOf(char_arr): My Name
将部分字符数组转为字符串:
String.copyValueOf(char_arr, 3, 4): Name
字符串转为字符数组,再排序:
str.toCharArray(): IMMNWaegimnoosy
字节数组转为字符串:
new String(b_arr):bc
将基本数据类型转为字符串: 12.1231231
4.替换操作….
初始字符串:My Name Is WingooM
Wy Name Is WingooW
5切割….
str.split(” “): Wy-Name-Is
6求子串….
初始串:Wy Name Is WingooW
str.substring(3, 6): Na
7大小写转换,去空格,比较….
str.toUpperCase(): WY NAME IS WINGOOW
str.toLowerCase(): wy name is wingoow
Welcome to Tutorialspoint.com
str.trim():
Welcome to Tutorialspoint.com
StringBuffer
以下是StringBuffer类支持的主要方法:
序号 | 方法描述 |
---|---|
1 | public StringBuffer append(String s) |
将指定的字符串追加到此字符序列 | |
2 | public StringBuffer reverse() |
将此字符序列用其反转形式取代 | |
3 | public delete(int start, int end) |
移除此序列的子字符串中的字符 | |
4 | public insert(int offset, int i) |
将 int 参数的字符串表示形式插入此序列中 | |
5 | replace(int start, int end, String str) |
使用给定 String 中的字符替换此序列的子字符串中的字符 |
下面的列表里的方法和String类的方法类似:
序号 | 方法描述 |
---|---|
1 | int capacity() |
返回当前容量 | |
2 | char charAt(int index) |
返回此序列中指定索引处的 char 值 | |
3 | void ensureCapacity(int minimumCapacity) |
确保容量至少等于指定的最小值 | |
4 | void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) |
将字符从此序列复制到目标字符数组 dst | |
5 | int indexOf(String str) |
返回第一次出现的指定子字符串在该字符串中的索引 | |
6 | int indexOf(String str, int fromIndex) |
从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引 | |
7 | int lastIndexOf(String str) |
返回最右边出现的指定子字符串在此字符串中的索引 | |
8 | int lastIndexOf(String str, int fromIndex) |
返回最后一次出现的指定子字符串在此字符串中的索引 | |
9 | int length() |
返回长度(字符数) | |
10 | void setCharAt(int index, char ch) |
将给定索引处的字符设置为 ch | |
11 | void setLength(int newLength) |
设置字符序列的长度 | |
12 | CharSequence subSequence(int start, int end) |
返回一个新的字符序列,该字符序列是此序列的子序列 | |
13 | String substring(int start) |
返回一个新的 String,它包含此字符序列当前所包含的字符子序列 | |
14 | String substring(int start, int end) |
返回一个新的 String,它包含此序列当前所包含的字符子序列 | |
15 | String toString() |
返回此序列中数据的字符串表示形式 |