源码分析
String str = new String();//new char[0]
String str1 = new String(“abc”);//new char[]{‘a’, ‘b’, ‘c’};
StringBuffer sb1 = new StringBuffer();//new char[16];底层创建了一个长度是16的数组。
sb1.append(‘a’);//value[0] = ‘a’;
sb1.append(‘b’);//value[1] = ‘b’;
每次造完,额外空出16个字符
StringBuffer sb2 = new StringBuffer(“abc”);//char[] value = new char[“abc”.length() + 16];
问题一:
sout.sb2.length();//3
问题二:扩容问题:如果要添加的数据底层数组存不下了,那就需要扩容底层的数组。
默认情况下,扩容为原来的2倍+2,同时将原有数组中的元素复制到新的数组中。
开发中建议使用StringBuffer(int capacity)或StringBuilder(int capacity)
@Test
public void test1(){
StringBuffer sb1 = new StringBuffer("abc");
sb1.setCharAt(0, 'm');
System.out.println(sb1);//mbc
System.out.println(sb1.length());//3
StringBuffer str2 = new StringBuffer();
System.out.println(str2.length());//0
}
总结:
- 增:append(xxx)
- 删:delete(int start, int end)
- 改:setCharAt(int n, char ch)/replace(int start, int end)
- 查:charAt(int n)
- 插:insert(int offset, xxx)
- 长度:length()
- 遍历:for + charAt()/toString()
@Test
public void test2(){
StringBuffer s1 = new StringBuffer("abc");
s1.append(1);
s1.append('1');
System.out.println(s1);//StringBuffer
// s1.delete(2, 4);//左闭又开//ab1
// s1.replace(2, 4, "hello");//abhello1
// s1.insert(2, false);//abfalsec11
// System.out.println(s1.length());//10
// s1.reverse();//11cba
String s2 = s1.substring(1, 3);
System.out.println(s2);//bc
System.out.println(s1);//abc11
}
对比String、StringBuffer、StringBuilder三者效率
@Test
public void test3(){
//初始设置
long startTime = 0L;
long endTime = 0L;
String text = "";
StringBuffer buffer = new StringBuffer("");
StringBuilder builder = new StringBuilder("");
//开始对比
startTime = System.currentTimeMillis();
for (int i = 0; i < 200000; i++){
buffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer的执行时间为:" + (endTime - startTime));//63
startTime = System.currentTimeMillis();
for (int i = 0; i < 200000; i++){
builder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的执行时间为:" + (endTime - startTime));//47
startTime = System.currentTimeMillis();
for (int i = 0; i < 200000; i++){
text = text + i;
}
endTime = System.currentTimeMillis();
System.out.println("String的执行时间为:" + (endTime - startTime));//44126
}
练习: 将一个字符串进行反转。将字符串中指定部分进行反转。比如“abcdefg”–>“abfedcg”
方式一:转换为char[]
public String reverse(String str, int startIndex, int endIndex) {
if (str != null && str.length() != 0) {
char[] arr = str.toCharArray();
for (int x = startIndex, y = endIndex; x < y; x++, y--) {
char temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
return new String(arr);
}
return null;
}
@Test
public void testReverse(){
long startTime = 0L;
long endTime = 0L;
String str = "abcdefg";
startTime = System.currentTimeMillis();
String reverse = reverse(str, 2, 5);
System.out.println(reverse);//abfedcg
endTime = System.currentTimeMillis();
System.out.println("方式一执行时间为:" + (endTime - startTime));
startTime = System.currentTimeMillis();
String reverse1 = reverse1(str, 2, 5);
System.out.println(reverse1);//abfedcg
endTime = System.currentTimeMillis();
System.out.println("方式二的执行时间为:" + (endTime - startTime));
startTime = System.currentTimeMillis();
String reverse2 = reverse2(str, 2, 5);
System.out.println(reverse2);//abfedcg
endTime = System.currentTimeMillis();
System.out.println("方式三的执行时间为:" + (endTime - startTime));
}
方式二:使用String的拼接(每次都得新造)
public String reverse1(String str, int startIndex, int endIndex) {
if (str != null && str.length() != 0) {
//第一部分
String reverseStr = str.substring(0, startIndex);
//第二部分
for (int i = endIndex; i >= startIndex; i--) {
reverseStr += str.charAt(i);
}
//第三部分
reverseStr += str.substring(endIndex + 1);
return reverseStr;
}
return null;
}
方式三:使用StringBuffer/StringBuilder替换String
public String reverse2(String str, int startIndex, int endIndex) {
if (str != null && str.length() != 0) {
StringBuilder builder = new StringBuilder(str.length());
//第一部分
builder.append(str.substring(0, startIndex));
//第二部分
for (int i = endIndex; i >= startIndex; i--) {
builder.append(str.charAt(i));
}
//第三部分
builder.append(str.substring(endIndex + 1));
return builder.toString();//装换成String形式
}
return null;
}
练习:获取一个字符串在另一个字符串中出现的次数比如获取“ab”在“abkkcabkabkebkebfkabkakab”中出现的次数
public int getCount(String mainStr, String subStr){
int mainLength = mainStr.length();
int subLength = subStr.length();
int count = 0;
int index = 0;
if (mainLength >= subLength){
//方式一:
// while ((index = mainStr.indexOf(subStr)) != -1){
// count ++;
// mainStr = mainStr.substring(index + subStr.length());//每次都对mainStr重新赋值
// }
//方式二:改进
while((index = mainStr.indexOf(subStr, index)) != -1){
count ++;
index += subLength;
}
return count;
}else{
return 0;
}
}
@Test
public void test1(){
String mainStr = "abkkcabkabkebkebfkabkakab";
String subStr = "ab";
int count = getCount(mainStr, subStr);
System.out.println(count);//5
}
练习:获取两个字符串中最大相同子串。
比如:str1 = “abcwerthelloyuiodef”;str2 = “cvhellobnm”;
提示:将短的那个串进行长度依次递减的子串与较长的串比较。
前提:两个字符串中最大子串只有一个
public String getMaxSameString(String str1, String str2) {
if (str1 != null && str2 != null) {
String maxStr = str1.length() >= str2.length() ? str1 : str2;
String minStr = str1.length() < str2.length() ? str1 : str2;
int length = minStr.length();
for (int i = 0; i < length; i++) {
for (int x = 0, y = length - i; y <= length; x++, y++) {
String substr = minStr.substring(x, y);
if (maxStr.contains(substr)) {
return substr;
}
}
}
}
return null;
}
@Test
public void test(){
String str1 = "abcwerthelloyuiodef";
String str2 = "cvhellobnm";
String maxSameString = getMaxSameString(str1, str2);
System.out.println(maxSameString);//hello
}