数据结构---Java---String、StringBuilder、StringBuffer
1、概述
1.1 String:不可变字符串
String的存储位置:
1 2 3 4 5 | String s1= "a" ; String s2= "a" ; String s3= new String( "a" ); System.out.println(s1==s2); //true System.out.println(s1==s3); //false |
String s="a";
一个对象,常量池“a”
这种方式创建字符串 ,首先去 方法区的常量池 找是否有 "a"对象,如果有,直接返回;没有在常量池创建一个"a"对象;
String s3=new String("a");
创建2个对象,一个在常量池“a”、一个在堆s3指向的字符串对象;
首先去常量池找是否有"a"字符串,如果没有,常量池创建"a"对象,堆创建 s3指向的对象;
1.2、StringBuffer:可改变的字符串,线程安全
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | abstract class AbstractStringBuilder implements Appendable, CharSequence { char [] value; AbstractStringBuilder( int capacity) { value = new char [capacity]; } public AbstractStringBuilder append(String str) { if (str == null ) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars( 0 , len, value, count); count += len; return this ; } public AbstractStringBuilder append(StringBuffer sb) { if (sb == null ) return appendNull(); int len = sb.length(); ensureCapacityInternal(count + len); sb.getChars( 0 , len, value, count); count += len; return this ; } public AbstractStringBuilder reverse() { boolean hasSurrogates = false ; int n = count - 1 ; for ( int j = (n- 1 ) >> 1 ; j >= 0 ; j--) { int k = n - j; char cj = value[j]; char ck = value[k]; value[j] = ck; value[k] = cj; if (Character.isSurrogate(cj) || Character.isSurrogate(ck)) { hasSurrogates = true ; } } if (hasSurrogates) { reverseAllValidSurrogatePairs(); } return this ; } } public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence { public StringBuffer() { super ( 16 ); } @Override public synchronized StringBuffer append(String str) { toStringCache = null ; super .append(str); return this ; } public synchronized StringBuffer append(StringBuffer sb) { toStringCache = null ; super .append(sb); return this ; } @Override public synchronized StringBuffer reverse() { toStringCache = null ; super .reverse(); return this ; } } |
1.3、 StringBuilder:可改变的字符串,线程不安全
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | abstract class AbstractStringBuilder implements Appendable, CharSequence { char [] value; AbstractStringBuilder( int capacity) { value = new char [capacity]; } public AbstractStringBuilder append(String str) { if (str == null ) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars( 0 , len, value, count); count += len; return this ; } public AbstractStringBuilder append(StringBuffer sb) { if (sb == null ) return appendNull(); int len = sb.length(); ensureCapacityInternal(count + len); sb.getChars( 0 , len, value, count); count += len; return this ; } public AbstractStringBuilder reverse() { boolean hasSurrogates = false ; int n = count - 1 ; for ( int j = (n- 1 ) >> 1 ; j >= 0 ; j--) { int k = n - j; char cj = value[j]; char ck = value[k]; value[j] = ck; value[k] = cj; if (Character.isSurrogate(cj) || Character.isSurrogate(ck)) { hasSurrogates = true ; } } if (hasSurrogates) { reverseAllValidSurrogatePairs(); } return this ; } } public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence { public StringBuilder() { super ( 16 ); } public StringBuilder( int capacity) { super (capacity); } @Override public StringBuilder append(String str) { super .append(str); return this ; } public StringBuilder append(StringBuffer sb) { super .append(sb); return this ; } @Override public StringBuilder reverse() { super .reverse(); return this ; } @Override public String toString() { // Create a copy, don't share the array return new String(value, 0 , count); } } |
2、字符串操作
2.1、返回指定位置的字符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | String public char charAt( int index) { if ((index < 0 ) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return value[index]; } StringBuilder 无 StringBuffer @Override public synchronized char charAt( int index) { if ((index < 0 ) || (index >= count)) throw new StringIndexOutOfBoundsException(index); return value[index]; } |
2.2、返回指定字符 的位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | 1 、String public int indexOf( int ch) { return indexOf(ch, 0 ); } public int indexOf( int ch, int fromIndex) { final int max = value.length; if (fromIndex < 0 ) { fromIndex = 0 ; } else if (fromIndex >= max) { // Note: fromIndex might be near -1>>>1. return - 1 ; } if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { // handle most cases here (ch is a BMP code point or a // negative value (invalid code point)) final char [] value = this .value; for ( int i = fromIndex; i < max; i++) { if (value[i] == ch) { return i; } } return - 1 ; } else { return indexOfSupplementary(ch, fromIndex); } } 2 、StringBuilder @Override public int indexOf(String str) { return super .indexOf(str); } 使用父类AbstractStringBuilder public int indexOf(String str) { return indexOf(str, 0 ); } public int indexOf(String str, int fromIndex) { return String.indexOf(value, 0 , count, str, fromIndex); } 使用String static int indexOf( char [] source, int sourceOffset, int sourceCount, String target, int fromIndex) { return indexOf(source, sourceOffset, sourceCount, target.value, 0 , target.value.length, fromIndex); } 3 、StringBuffer @Override public int indexOf(String str) { // Note, synchronization achieved via invocations of other StringBuffer methods return super .indexOf(str); } 同 StringBuilder |
2.3、字符串截取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 1 、String public String substring( int beginIndex) { if (beginIndex < 0 ) { throw new StringIndexOutOfBoundsException(beginIndex); } int subLen = value.length - beginIndex; if (subLen < 0 ) { throw new StringIndexOutOfBoundsException(subLen); } return (beginIndex == 0 ) ? this : new String(value, beginIndex, subLen); } 2 、StringBuilder 无 3 、StringBuffer @Override public synchronized String substring( int start) { return substring(start, count); } @Override public synchronized String substring( int start, int end) { return super .substring(start, end); } 使用父类 AbstractStringBuilder public String substring( int start, int end) { if (start < 0 ) throw new StringIndexOutOfBoundsException(start); if (end > count) throw new StringIndexOutOfBoundsException(end); if (start > end) throw new StringIndexOutOfBoundsException(end - start); return new String(value, start, end - start); } |
2.4、字符串拼接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 1 、String public String concat(String str) { int otherLen = str.length(); if (otherLen == 0 ) { return this ; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true ); } 2 、StringBuilder @Override public StringBuilder append(String str) { super .append(str); return this ; } 父类AbstractStringBuilder public AbstractStringBuilder append(String str) { if (str == null ) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars( 0 , len, value, count); count += len; return this ; } 3 、StringBuffer @Override public synchronized StringBuffer append(String str) { toStringCache = null ; super .append(str); return this ; } 父类AbstractStringBuilder public AbstractStringBuilder append(String str) { if (str == null ) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars( 0 , len, value, count); count += len; return this ; } |
2.5、按指定 规则 切割
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | 1 、String public String[] split(String regex) { return split(regex, 0 ); } public String[] split(String regex, int limit) { /* fastpath if the regex is a (1)one-char String and this character is not one of the RegEx's meta characters ".$|()[{^?*+\\", or (2)two-char String and the first char is the backslash and the second is not the ascii digit or ascii letter. */ char ch = 0 ; if (((regex.value.length == 1 && ".$|()[{^?*+\\" .indexOf(ch = regex.charAt( 0 )) == - 1 ) || (regex.length() == 2 && regex.charAt( 0 ) == '\\' && (((ch = regex.charAt( 1 ))- '0' )|( '9' -ch)) < 0 && ((ch- 'a' )|( 'z' -ch)) < 0 && ((ch- 'A' )|( 'Z' -ch)) < 0 )) && (ch < Character.MIN_HIGH_SURROGATE || ch > Character.MAX_LOW_SURROGATE)) { int off = 0 ; int next = 0 ; boolean limited = limit > 0 ; ArrayList<String> list = new ArrayList<>(); while ((next = indexOf(ch, off)) != - 1 ) { if (!limited || list.size() < limit - 1 ) { list.add(substring(off, next)); off = next + 1 ; } else { // last one //assert (list.size() == limit - 1); list.add(substring(off, value.length)); off = value.length; break ; } } // If no match was found, return this if (off == 0 ) return new String[]{ this }; // Add remaining segment if (!limited || list.size() < limit) list.add(substring(off, value.length)); // Construct result int resultSize = list.size(); if (limit == 0 ) { while (resultSize > 0 && list.get(resultSize - 1 ).length() == 0 ) { resultSize--; } } String[] result = new String[resultSize]; return list.subList( 0 , resultSize).toArray(result); } return Pattern.compile(regex).split( this , limit); } 2 、StringBuilder 无 3 、StringBuffer 无 |
2.6、字符串倒序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | 1 、String 无 2 、StringBuilder @Override public StringBuilder reverse() { super .reverse(); return this ; } 父类AbstractStringBuilder public AbstractStringBuilder reverse() { boolean hasSurrogates = false ; int n = count - 1 ; for ( int j = (n- 1 ) >> 1 ; j >= 0 ; j--) { int k = n - j; char cj = value[j]; char ck = value[k]; value[j] = ck; value[k] = cj; if (Character.isSurrogate(cj) || Character.isSurrogate(ck)) { hasSurrogates = true ; } } if (hasSurrogates) { reverseAllValidSurrogatePairs(); } return this ; } 3 、StringBuffer @Override public synchronized StringBuffer reverse() { toStringCache = null ; super .reverse(); return this ; } 父类AbstractStringBuilder public AbstractStringBuilder reverse() { boolean hasSurrogates = false ; int n = count - 1 ; for ( int j = (n- 1 ) >> 1 ; j >= 0 ; j--) { int k = n - j; char cj = value[j]; char ck = value[k]; value[j] = ck; value[k] = cj; if (Character.isSurrogate(cj) || Character.isSurrogate(ck)) { hasSurrogates = true ; } } if (hasSurrogates) { reverseAllValidSurrogatePairs(); } return this ; } |
3、字符串创建形式
3.1、String s ="1";
创建一个"1"对象,存放于常量池
3.2、String s2=new String("1");
创建一个 "1"对象 或 2个 s2指向的对象+"1"对象
4、字符串拼接形式
4.1、String s1=”1”+”2”+”3”;
创建一个"123"对象,存放于常量池;
4.2、String s2=”1”+”3”+new String(“1”)+”4”;
创建 "13"对象+ "1"对象 + "4"对象 + String对象1+ String对象 1314
4.3、String s3=new String(“1”)+new String(“1”);
创建 "1"对象 + String1对象 + String1对象 + String11对象
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)