æ·±å ¥è§£è¯»Stringç±»çæºç
ææ£å卿²å䏿´¥æ´¥æå³å°è¯»å欣大佬çãç å翻身ãââJava å¸å½è¿ä¸ç« ï¼é¨éåäºã起身æå¼é¨ä¸çï¼æ¯ä¸å¦¹ï¼å¥¹ä»å¦æ ¡åæ¥äºã
âä¸å¦¹ï¼ä½ 忥ççåæ¶ï¼ä»å¤©æä»¬æç®è®² Java ä¸çå符串å¢ãâçä¸å¦¹æ¢éçæ¶åæè¯´ã
âå¦ï¼å¯ä»¥åï¼å¥ãå¬è¯´å符串çç»èç¹å«å¤ï¼ä»ä¹åç¬¦ä¸²å¸¸éæ± äºãå符串ä¸å¯åæ§äºãåç¬¦ä¸²æ¼æ¥äºãå符串é¿åº¦éå¶äºççï¼ä½ æå¥½æ ¢æ ¢è®²ï¼å¦åæå¯è½ä¸æ¶å伿¶åä¸äºãâä¸å¦¹çæåº¦æ¾å¾å¾è¯æ³ã
âå¯ï¼æå·²ç»æ³å¥½äºï¼ä»å¤©å°±åªå¸¦ä½ 大æ¦è®¤è¯ä¸ä¸å符串ï¼ä¸»è¦è¯»ä¸è¯»å®çæºç ï¼å ¶ä»çç»èå±ä»¬åé¢åæ ¢æ ¢è®²ï¼ä¿è¯ä½ è½åæ¶æ¶åãâ
â好ï¼é£å°±å¼å§å§ãâä¸å¦¹å·²ç»åå¤å¥½åå¨äºçµèæ¡çè¾¹ä¸ã
æåºäºä¸å£°åèµ°å°çµèæ¡åå䏿¥ï¼é¡ºææå¼ Intellij IDEAï¼å¹¶æ¾å°äº String çæºç ï¼Java 8 çæ¬ï¼ã
String ç±»ç声æ
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
}â第ä¸ï¼String ç±»æ¯ final çï¼æå³çå®ä¸è½è¢«å类继æ¿ãè¿äºç¥è¯æä»¬è®²é¢å对象ç¼ç¨çæ¶åé½ä¼è®²å°ï¼ä¸å¦¹ä½ ä¸ç¨æ å¿ãâ
â第äºï¼String ç±»å®ç°äº Serializable æ¥å£ï¼æå³çå®å¯ä»¥åºååï¼åé¢åæ ·ä¼è®²ï¼æ³é¾æ¥å¯è·³è½¬ï¼ãâ
â第ä¸ï¼String ç±»å®ç°äº Comparable æ¥å£ï¼æå³çæå¥½ä¸è¦ç¨â==âæ¥æ¯è¾ä¸¤ä¸ªå符串æ¯å¦ç¸çï¼èåºè¯¥ç¨ compareTo() æ¹æ³å»æ¯è¾ãâ
å 为 == æ¯ç¨æ¥æ¯è¾ä¸¤ä¸ªå¯¹è±¡çå°åï¼è¿ä¸ªå¨è®²å符串æ¯è¾çæ¶åä¼è¯¦ç»è®²ãå¦æåªæ¯è¯´æ¯è¾å符串å 容çè¯ï¼å¯ä»¥ä½¿ç¨ String ç±»ç equals æ¹æ³ï¼æºç åæ³¨éå¦ä¸æç¤ºï¼
public boolean equals(Object anObject) {
// æ£æ¥æ¯å¦æ¯åä¸ä¸ªå¯¹è±¡çå¼ç¨ï¼å¦ææ¯ï¼ç´æ¥è¿å true
if (this == anObject) {
return true;
}
// æ£æ¥ anObject æ¯å¦æ¯ String ç±»çå®ä¾
if (anObject instanceof String) {
String anotherString = (String) anObject; // å° anObject 强å¶è½¬æ¢ä¸º String ç±»å
int n = value.length; // è·åå½åå符串çé¿åº¦
// æ£æ¥ä¸¤ä¸ªå符串é¿åº¦æ¯å¦ç¸ç
if (n == anotherString.value.length) {
char v1[] = value; // å½åå符串çå符æ°ç»
char v2[] = anotherString.value; // å¦ä¸ä¸ªå符串çå符æ°ç»
int i = 0; // ç¨äºéåå符æ°ç»çç´¢å¼
// é忝è¾ä¸¤ä¸ªåç¬¦ä¸²çæ¯ä¸ªå符
while (n-- != 0) {
// 妿å¨ä»»ä½ä½ç½®å符ä¸åï¼åè¿å false
if (v1[i] != v2[i])
return false;
i++;
}
// ææå符é½ç¸åï¼è¿å true
return true;
}
}
// 妿 anObject 䏿¯ String ç±»åæé¿åº¦ä¸çï¼åè¿å false
return false;
}â第åï¼String å StringBufferãStringBuilder 䏿 ·ï¼é½å®ç°äº CharSequence æ¥å£ï¼æä»¥å®ä»¬ä»¨å±äºè¿äº²ãç±äº String æ¯ä¸å¯åçï¼æä»¥éå°åç¬¦ä¸²æ¼æ¥çæ¶åå°±å¯ä»¥èèä¸ä¸ String çå¦å¤ä¸¤ä¸ªå¥½å å¼ï¼StringBuffer å StringBuilderï¼å®ä¿©æ¯å¯åçãâ
String åºå±ä¸ºä»ä¹ç± char æ°ç»ä¼å为 byte æ°ç»
private final char value[];â第äºï¼Java 9 以åï¼String æ¯ç¨ char åæ°ç»å®ç°çï¼ä¹åæ¹æäº byte åæ°ç»å®ç°ï¼å¹¶å¢å äº coder æ¥è¡¨ç¤ºç¼ç ãè¿æ ·åç好夿¯å¨ Latin1 å符为主çç¨åºéï¼å¯ä»¥æ String å ç¨çå ååå°ä¸åãå½ç¶ï¼å¤©ä¸æ²¡æå è´¹çåé¤ï¼è¿ä¸ªæ¹è¿å¨èçå åçåæ¶å¼å ¥äºç¼ç æ£æµçå¼éãâ
Latin1ï¼Latin-1ï¼æ¯ä¸ç§ååèå符éï¼å³æ¯ä¸ªå符åªä½¿ç¨ä¸ä¸ªåèçç¼ç æ¹å¼ï¼ï¼ä¹ç§°ä¸º ISO-8859-1ï¼å½é æ ååç»ç» 8859-1ï¼ï¼å®å å«äºè¥¿æ¬§è¯è¨ä¸ä½¿ç¨çææå符ï¼å æ¬è±è¯ãæ³è¯ãå¾·è¯ã西ççè¯ãè¡èçè¯ãæå¤§å©è¯ççãå¨ Latin1 ç¼ç ä¸ï¼æ¯ä¸ªå符使ç¨ä¸ä¸ª 8 ä½ï¼å³ä¸ä¸ªåèï¼çç¼ç ï¼å¯ä»¥è¡¨ç¤º 256 ç§ä¸åçå符ï¼å ¶ä¸å æ¬ ASCII å符éä¸çææå符ï¼å³ 0x00 å° 0x7Fï¼ä»¥åå ¶ä»è¥¿æ¬§è¯è¨ä¸çç¹æ®å符ï¼ä¾å¦ éãüãñ ççãç±äº Latin1 åªä½¿ç¨ä¸ä¸ªåè表示ä¸ä¸ªå符ï¼å æ¤å¨åå¨åä¼ è¾ææ¬æ¶å ·æè¾å°çåå¨ç©ºé´åè¾å¿«çé度
ä¸é¢æ¯ JDK 11 çæ¬ä¸ç String ç±»æºç ï¼æ³¨æå JDK 8 çä¸åã
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
@Stable
private final byte[] value;
private final byte coder;
private int hash;
}ä» char[] å° byte[]ï¼æä¸»è¦çç®çæ¯èçå符串å ç¨çå
å空é´ãå
åå ç¨åå°å¸¦æ¥çå¦å¤ä¸ä¸ªå¥½å¤ï¼å°±æ¯ GC 次æ°ä¹ä¼åå°ã
GCï¼ä¹å°±æ¯åå¾åæ¶ï¼JVM çæ¶åä¼è®²å°ãå¯ä»¥æ³é¾æ¥äºè§£ã
è¿éç»ä½ 讲ä¸ä¸ªå°ç¥è¯ã
æä»¬ä½¿ç¨ jmap -histo:live pid | head -n 10 å½ä»¤å°±å¯ä»¥æ¥çå°å å
对象示ä¾çç»è®¡ä¿¡æ¯ãClassLoader çä¿¡æ¯ä»¥å finalizer éåçã
Java çå¯¹è±¡åºæ¬ä¸é½å¨å ä¸ãåé¢ä¹ä¼è®²ãè¿éç pid å°±æ¯è¿ç¨å·ï¼å¯ä»¥éè¿
ps -ef | grep javaå½ä»¤æ¥çï¼ä¸å¾ä¸çº¢è²æ¡åºæ¥ç第äºé¡¹å°±æ¯ pidã

就以æ£å¨è¿è¡ççç¼ç¨åµé¡¹ç®æ¥è¯´å§ï¼å®æ¯ä»¥ JDK 8 è¿è¡çï¼ï¼ç»ææ¯è¿æ ·çã

å ¶ä¸ String 对象æ 17638 个ï¼å ç¨äº 423312 个åèçå åï¼æå¨ç¬¬ä¸ä½ã
ç±äº Java 8 ç String å
é¨å®ç°ä»ç¶æ¯ char[]ï¼æä»¥æä»¬å¯ä»¥çå°å
åå ç¨æå¨ç¬¬ 1 ä½çå°±æ¯ char æ°ç»ã
char[] 对象æ 17673 个ï¼å ç¨äº 1621352 个åèçå
åï¼æå¨ç¬¬ä¸ä½ã
é£ä¹å°±æ¯è¯´ä¼å String èçå åç©ºé´æ¯é常æå¿ è¦çï¼å¦ææ¯å»ä¼åä¸ä¸ªä½¿ç¨é¢ç没æ String è¿ä¹é«çç±»ï¼å°±æ²¡ä»ä¹å¿ è¦ï¼å¯¹å§ï¼
伿å¨ç¥ï¼char ç±»åçæ°æ®å¨ JVM 䏿¯å ç¨ä¸¤ä¸ªåèçï¼å¹¶ä¸ä½¿ç¨çæ¯ UTF-8 ç¼ç ï¼å ¶å¼èå´å¨ '\u0000'ï¼0ï¼å '\uffff'ï¼65,535ï¼ï¼å å«ï¼ä¹é´ã
ä¹å°±æ¯è¯´ï¼ä½¿ç¨ char[] æ¥è¡¨ç¤º String å°±ä¼å¯¼è´ï¼å³ä½¿ String ä¸çå符åªç¨ä¸ä¸ªåèå°±è½è¡¨ç¤ºï¼ä¹å¾å ç¨ä¸¤ä¸ªåèã
PSï¼å¨è®¡ç®æºä¸ï¼ååèå符é常æçæ¯ä¸ä¸ªåèï¼8 ä½ï¼å¯ä»¥è¡¨ç¤ºçå符ï¼èååèå符åæéè¦ä¸¤ä¸ªåèï¼16 ä½ï¼æè½è¡¨ç¤ºçå符ãååèå符åååèå符çå®ä¹æ¯ç¸å¯¹çï¼ä¸åçç¼ç æ¹å¼å¯¹åºçååèåååèå符éä¹ä¸åã常è§çååèåç¬¦éæ ASCIIï¼ç¾å½ä¿¡æ¯äº¤æ¢æ å代ç ï¼ãISO-8859ï¼å½é æ ååç»ç»æ åç¼å· 8859ï¼ãGBKï¼æ±åå ç æ©å±è§èï¼ãGB2312ï¼ä¸å½å½å®¶æ åï¼ç°å¨å·²ç»è¢« GBK å代ï¼ï¼åæä¸åæ¯ãæ°åãæ ç¹ç¬¦å·ãæ§å¶åç¬¦é½æ¯ååèå符ãååèå符éå æ¬ UnicodeãUTF-8ãGB18030ï¼ä¸å½å½å®¶æ åï¼ï¼ä¸æãæ¥æã驿ãæä¸ææ©å±å符å±äºååèå符ã
å½ç¶äºï¼ä»
ä»
å° char[] ä¼å为 byte[] æ¯ä¸å¤çï¼è¿è¦é
å Latin-1 çç¼ç æ¹å¼ï¼è¯¥ç¼ç æ¹å¼æ¯ç¨å个åèæ¥è¡¨ç¤ºå符çï¼è¿æ ·å°±æ¯ UTF-8 ç¼ç èçäºæ´å¤ç空é´ã
æ¢å¥è¯è¯´ï¼å¯¹äºï¼
String name = "jack";è¿æ ·çï¼ä½¿ç¨ Latin-1 ç¼ç ï¼å ç¨ 4 个åèå°±å¤äºã
ä½å¯¹äºï¼
String name = "å°äº";è¿ç§ï¼æ¨çåæ³ï¼åªè½ä½¿ç¨ UTF16 æ¥ç¼ç ã
é对 JDK 9 ç String æºç éï¼ä¸ºäºåºå«ç¼ç æ¹å¼ï¼è¿½å äºä¸ä¸ª coder åæ®µæ¥åºåã
/**
* The identifier of the encoding used to encode the bytes in
* {@code value}. The supported values in this implementation are
*
* LATIN1
* UTF16
*
* @implNote This field is trusted by the VM, and is a subject to
* constant folding if String instance is constant. Overwriting this
* field after construction will cause problems.
*/
private final byte coder;Java 伿 ¹æ®å符串çå 容èªå¨è®¾ç½®ä¸ºç¸åºçç¼ç ï¼è¦ä¹ Latin-1 è¦ä¹ UTF16ã
ä¹å°±æ¯è¯´ï¼ä» char[] å° byte[]ï¼ä¸ææ¯ä¸¤ä¸ªåèï¼çº¯è±ææ¯ä¸ä¸ªåèï¼å¨æ¤ä¹åå¢ï¼ä¸ææ¯ä¸¤ä¸ªåèï¼è±æä¹æ¯ä¸¤ä¸ªåèã
å¨ UTF-8 ä¸ï¼0-127 å·çåç¬¦ç¨ 1 个åèæ¥è¡¨ç¤ºï¼ä½¿ç¨å ASCII ç¸åçç¼ç ãåªæ 128 å·å以ä¸çå符æç¨ 2 个ã3 个æè 4 个åèæ¥è¡¨ç¤ºã
- å¦æåªæä¸ä¸ªåèï¼é£ä¹æé«çæ¯ç¹ä½ä¸º 0ï¼
- 妿æå¤ä¸ªåèï¼é£ä¹ç¬¬ä¸ä¸ªåè仿é«ä½å¼å§ï¼è¿ç»æå 个æ¯ç¹ä½çå¼ä¸º 1ï¼å°±ä½¿ç¨å 个åèç¼ç ï¼å©ä¸çåèå以 10 å¼å¤´ã
å ·ä½ç表ç°å½¢å¼ä¸ºï¼
- 0xxxxxxxï¼ä¸ä¸ªåèï¼
- 110xxxxx 10xxxxxxï¼ä¸¤ä¸ªåèç¼ç å½¢å¼ï¼å¼å§ä¸¤ä¸ª 1ï¼ï¼
- 1110xxxx 10xxxxxx 10xxxxxxï¼ä¸åèç¼ç å½¢å¼ï¼å¼å§ä¸ä¸ª 1ï¼ï¼
- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxxï¼ååèç¼ç å½¢å¼ï¼å¼å§å个 1ï¼ã
ä¹å°±æ¯è¯´ï¼UTF-8 æ¯åé¿çï¼é£å¯¹äº String è¿ç§æéæºè®¿é®æ¹æ³çç±»æ¥è¯´ï¼å°±å¾ä¸æ¹ä¾¿ãæè°çéæºè®¿é®ï¼å°±æ¯ charAtãsubString è¿ç§æ¹æ³ï¼é便æå®ä¸ä¸ªæ°åï¼String è¦è½ç»åºç»æã妿å符串ä¸çæ¯ä¸ªå符å ç¨çå 忝ä¸å®é¿çï¼é£ä¹è¿è¡éæºè®¿é®çæ¶åï¼å°±éè¦ä»å¤´å¼å§æ°æ¯ä¸ªå符çé¿åº¦ï¼æè½æ¾å°ä½ æ³è¦çå符ã
é£ä½ å¯è½ä¼é®ï¼UTF-16 乿¯åé¿çå¢ï¼ä¸ä¸ªå符è¿å¯è½å ç¨ 4 个åèå¢ï¼
çç¡®ï¼UTF-16 ä½¿ç¨ 2 个æè 4 个åèæ¥åå¨å符ã
- å¯¹äº Unicode ç¼å·èå´å¨ 0 ~ FFFF ä¹é´çå符ï¼UTF-16 使ç¨ä¸¤ä¸ªåèåå¨ã
- å¯¹äº Unicode ç¼å·èå´å¨ 10000 ~ 10FFFF ä¹é´çå符ï¼UTF-16 使ç¨å个åèåå¨ï¼å ·ä½æ¥è¯´å°±æ¯ï¼å°å符ç¼å·çæææ¯ç¹ä½åæä¸¤é¨åï¼è¾é«çä¸äºæ¯ç¹ä½ç¨ä¸ä¸ªå¼ä»äº D800~DBFF ä¹é´çååèåå¨ï¼è¾ä½çä¸äºæ¯ç¹ä½ï¼å©ä¸çæ¯ç¹ä½ï¼ç¨ä¸ä¸ªå¼ä»äº DC00~DFFF ä¹é´çååèåå¨ã
使¯å¨ Java ä¸ï¼ä¸ä¸ªå符ï¼charï¼å°±æ¯ 2 个åèï¼å 4 个åèçå符ï¼å¨ Java é乿¯ç¨ä¸¤ä¸ª char æ¥åå¨çï¼è String çåç§æä½ï¼é½æ¯ä»¥ Java çå符ï¼charï¼ä¸ºåä½çï¼charAt æ¯åå¾ç¬¬å 个 charï¼subString åç乿¯ç¬¬å 个å°ç¬¬å 个 char ç»æçå串ï¼çè³ length è¿åç齿¯ char ç个æ°ã
æä»¥ UTF-16 å¨ Java çä¸çéï¼å°±å¯ä»¥è§ä¸ºä¸ä¸ªå®é¿çç¼ç ã
åè龿¥ï¼https://www.zhihu.com/question/447224628
String ç±»ç hashCode æ¹æ³
â第å ï¼æ¯ä¸ä¸ªå符串é½ä¼æä¸ä¸ª hash å¼ï¼è¿ä¸ªåå¸å¼å¨å¾å¤§æ¦çæ¯ä¸ä¼éå¤çï¼å æ¤ String å¾é忥ä½ä¸º HashMapï¼åé¢ä¼ç»è®²ï¼çé®å¼ãâ
æ¥ç String ç±»ç hashCode æ¹æ³ã
private int hash; // ç¼åå符串çåå¸ç
public int hashCode() {
int h = hash; // ä»ç¼åä¸è·ååå¸ç
// 妿åå¸ç æªè¢«è®¡ç®è¿ï¼å³ä¸º 0ï¼ä¸å符串ä¸ä¸ºç©ºï¼å计ç®åå¸ç
if (h == 0 && value.length > 0) {
char val[] = value; // è·åå符串çå符æ°ç»
// éååç¬¦ä¸²çæ¯ä¸ªå符æ¥è®¡ç®åå¸ç
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i]; // ä½¿ç¨ 31 ä½ä¸ºä¹æ³å å
}
hash = h; // ç¼å计ç®åçåå¸ç
}
return h; // è¿ååå¸ç
}hashCode æ¹æ³é¦å æ£æ¥æ¯å¦å·²ç»è®¡ç®è¿åå¸ç ï¼å¦æå·²ç»è®¡ç®è¿ï¼åç´æ¥è¿åç¼åçåå¸ç ãå¦åï¼æ¹æ³å°ä½¿ç¨ä¸ä¸ªå¾ªç¯éååç¬¦ä¸²çææå符ï¼å¹¶ä½¿ç¨ä¸ä¸ªä¹æ³åå æ³çç»å计ç®åå¸ç ã
è¿ç§è®¡ç®æ¹æ³è¢«ç§°ä¸ºâ31 åå叿³âã计ç®å®æåï¼å°å¾å°çåå¸å¼åå¨å¨ hash æååéä¸ï¼ä»¥ä¾¿ä¸æ¬¡è°ç¨ hashCode æ¹æ³æ¶ç´æ¥è¿å该å¼ï¼èä¸éè¦éæ°è®¡ç®ãè¿æ¯ä¸ç§ç¼åä¼åï¼ç§°ä¸ºâæ°æ§è®¡ç®âã
31 åå叿³ï¼31-Hashï¼æ¯ä¸ç§ç®åææçå符串åå¸ç®æ³ï¼å¸¸ç¨äºå¯¹å符串è¿è¡åå¸å¤çãè¯¥ç®æ³çåºæ¬ææ³æ¯å°å符串ä¸çæ¯ä¸ªå符ä¹ä»¥ä¸ä¸ªåºå®çè´¨æ° 31 ç广¬¡æ¹ï¼å¹¶å°å®ä»¬ç¸å å¾å°åå¸å¼ãå ·ä½å°ï¼å设å符串为 sï¼é¿åº¦ä¸º nï¼å 31 ååå¸å¼è®¡ç®å ¬å¼å¦ä¸ï¼
H(s) = (s[0] * 31^(n-1)) + (s[1] * 31^(n-2)) + ... + (s[n-1] * 31^0)å
¶ä¸ï¼s[i]表示å符串 s ä¸ç¬¬ i 个å符ç ASCII ç å¼ï¼^表示å¹è¿ç®ã
31 åå叿³çä¼ç¹å¨äºç®åæå®ç°ï¼è®¡ç®é度快ï¼åæ¶ä¹æ¯è¾ååå°åå¸å¨åå¸è¡¨ä¸ã
hashCode æ¹æ³ï¼æä»¬ä¼å¨å¦å¤ä¸ä¸ªç« èé详ç»è®²ï¼æ³åé¢ç龿¥äºè§£ã
æä»¬å¯ä»¥éè¿ä»¥ä¸æ¹æ³æ¨¡æ String ç hashCode æ¹æ³ï¼
public class HashCodeExample {
public static void main(String[] args) {
String text = "æ²é»çäº";
int hashCode = computeHashCode(text);
System.out.println("å符串 \"" + text + "\" çåå¸ç æ¯: " + hashCode);
System.out.println("String ç hashCode " + text.hashCode());
}
public static int computeHashCode(String text) {
int h = 0;
for (int i = 0; i < text.length(); i++) {
h = 31 * h + text.charAt(i);
}
return h;
}
}çä¸ä¸ç»æï¼
å符串 "æ²é»çäº" çåå¸ç æ¯: 867758096
String ç hashCode 867758096ç»ææ¯ä¸æ ·çï¼åå¦å°äºå§ï¼
String ç±»ç substring æ¹æ³
String ç±»ä¸è¿æä¸ä¸ªæ¹æ³æ¯è¾å¸¸ç¨ substringï¼ç¨æ¥æªåå符串çï¼æ¥çæºç ã
public String substring(int beginIndex) {
// æ£æ¥èµ·å§ç´¢å¼æ¯å¦å°äº 0ï¼å¦ææ¯ï¼åæåº StringIndexOutOfBoundsException å¼å¸¸
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
// 计ç®åå符串çé¿åº¦
int subLen = value.length - beginIndex;
// æ£æ¥åå符串é¿åº¦æ¯å¦ä¸ºè´æ°ï¼å¦ææ¯ï¼åæåº StringIndexOutOfBoundsException å¼å¸¸
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
// å¦æèµ·å§ç´¢å¼ä¸º 0ï¼åè¿ååå符串ï¼å¦åï¼å建并è¿åæ°çå符串
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}substring æ¹æ³é¦å æ£æ¥åæ°çæææ§ï¼å¦æåæ°æ æï¼åæåº StringIndexOutOfBoundsException å¼å¸¸ï¼åé¢ä¼ç»è®²ï¼ãæ¥ä¸æ¥ï¼æ¹æ³æ ¹æ®åæ°è®¡ç®åå符串çé¿åº¦ã妿åå符串é¿åº¦å°äºé¶ï¼ä¹ä¼æåº StringIndexOutOfBoundsException å¼å¸¸ã
妿 beginIndex 为 0ï¼è¯´æå串ä¸åå符串ç¸åï¼ç´æ¥è¿ååå符串ãå¦åï¼ä½¿ç¨ value æ°ç»ï¼åå符串çå符æ°ç»ï¼çä¸é¨å new ä¸ä¸ªæ°ç String 对象并è¿åã
ä¸é¢æ¯å ä¸ªä½¿ç¨ substring æ¹æ³ç示ä¾ï¼
â ãæåå符串ä¸ç䏿®µå串ï¼
String str = "Hello, world!";
String subStr = str.substring(7, 12); // ä»ç¬¬7个å符ï¼å
æ¬ï¼æåå°ç¬¬12个å符ï¼ä¸å
æ¬ï¼
System.out.println(subStr); // è¾åº "world"â¡ãæåå符串ä¸çåç¼æåç¼ï¼
String str = "Hello, world!";
String prefix = str.substring(0, 5); // æåå5个å符ï¼å³ "Hello"
String suffix = str.substring(7); // æåä»ç¬¬7个å符å¼å§çææå符ï¼å³ "world!"â¢ãå¤çå符串ä¸çç©ºæ ¼ååé符ï¼
String str = " Hello, world! ";
String trimmed = str.trim(); // å»é¤å符串å¼å¤´åç»å°¾çç©ºæ ¼
String[] words = trimmed.split("\\s+"); // å°å符串æç
§ç©ºæ ¼åéæåè¯æ°ç»
String firstWord = words[0].substring(0, 1); // æå第ä¸ä¸ªåè¯çé¦åæ¯
System.out.println(firstWord); // è¾åº "H"â£ãå¤çå符串ä¸çæ°åå符å·ï¼
String str = "1234-5678-9012-3456";
String[] parts = str.split("-"); // å°å符串æç
§è¿å符åéæå个é¨å
String last4Digits = parts[3].substring(1); // æåæåä¸ä¸ªé¨åçåä¸ä½æ°å
System.out.println(last4Digits); // è¾åº "456"æ»ä¹ï¼substring æ¹æ³å¯ä»¥æ ¹æ®éæ±çµæ´»å°æåå符串ä¸çå串ï¼ä¸ºå符串å¤çæä¾äºä¾¿å©ã
String ç±»ç indexOf æ¹æ³
indexOf æ¹æ³ç¨äºæ¥æ¾ä¸ä¸ªåå符串å¨åå符串ä¸ç¬¬ä¸æ¬¡åºç°çä½ç½®ï¼å¹¶è¿å该ä½ç½®çç´¢å¼ãæ¥çè¯¥æ¹æ³çæºç ï¼
/*
* æ¥æ¾å符æ°ç» target å¨å符æ°ç» source ä¸ç¬¬ä¸æ¬¡åºç°çä½ç½®ã
* sourceOffset å sourceCount åæ°æå® source æ°ç»ä¸è¦æç´¢çèå´ï¼
* targetOffset å targetCount åæ°æå® target æ°ç»ä¸è¦æç´¢çèå´ï¼
* fromIndex åæ°æå®å¼å§æç´¢çä½ç½®ã
* 妿æ¾å°äº target æ°ç»ï¼åè¿åå®å¨ source æ°ç»ä¸çä½ç½®ç´¢å¼ï¼ä»0å¼å§ï¼ï¼
* å¦åè¿å-1ã
*/
static int indexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
// 妿å¼å§æç´¢çä½ç½®å·²ç»è¶
åº source æ°ç»çèå´ï¼åç´æ¥è¿å-1ï¼å¦æ target æ°ç»ä¸ºç©ºï¼åè¿å sourceCountï¼
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
// 妿å¼å§æç´¢çä½ç½®å°äº0ï¼åä»0å¼å§æç´¢
if (fromIndex < 0) {
fromIndex = 0;
}
// 妿 target æ°ç»ä¸ºç©ºï¼åç´æ¥è¿åå¼å§æç´¢çä½ç½®
if (targetCount == 0) {
return fromIndex;
}
// æ¥æ¾ target æ°ç»ç第ä¸ä¸ªåç¬¦å¨ source æ°ç»ä¸çä½ç½®
char first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount);
// å¾ªç¯æ¥æ¾ target æ°ç»å¨ source æ°ç»ä¸çä½ç½®
for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
// 妿 source æ°ç»ä¸å½åä½ç½®çåç¬¦ä¸æ¯ target æ°ç»ç第ä¸ä¸ªå符ï¼åå¨ source æ°ç»ä¸ç»§ç»æ¥æ¾ target æ°ç»ç第ä¸ä¸ªå符
if (source[i] != first) {
while (++i <= max && source[i] != first);
}
/* Found first character, now look at the rest of v2 */
// å¦æå¨ source æ°ç»ä¸æ¾å°äº target æ°ç»ç第ä¸ä¸ªå符ï¼åç»§ç»æ¥æ¾ target æ°ç»çå©ä½é¨åæ¯å¦å¹é
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end && source[j]
== target[k]; j++, k++);
// 妿 target æ°ç»å
¨é¨å¹é
ï¼åè¿åå¨ source æ°ç»ä¸çä½ç½®ç´¢å¼
if (j == end) {
/* Found whole string. */
return i - sourceOffset;
}
}
}
// æ²¡ææ¾å° target æ°ç»ï¼åè¿å-1
return -1;
}æ¥ç示ä¾ã
â ãç¤ºä¾ 1ï¼æ¥æ¾åå符串çä½ç½®
String str = "Hello, world!";
int index = str.indexOf("world"); // æ¥æ¾ "world" ååç¬¦ä¸²å¨ str ä¸ç¬¬ä¸æ¬¡åºç°çä½ç½®
System.out.println(index); // è¾åº 7â¡ãç¤ºä¾ 2ï¼æ¥æ¾åç¬¦ä¸²ä¸æä¸ªå符çä½ç½®
String str = "Hello, world!";
int index = str.indexOf(","); // æ¥æ¾éå·å¨ str ä¸ç¬¬ä¸æ¬¡åºç°çä½ç½®
System.out.println(index); // è¾åº 5â¢ãç¤ºä¾ 3ï¼æ¥æ¾åå符串çä½ç½®ï¼ä»æå®ä½ç½®å¼å§æ¥æ¾ï¼
String str = "Hello, world!";
int index = str.indexOf("l", 3); // ä»ç´¢å¼ä¸º3çä½ç½®å¼å§æ¥æ¾ "l" ååç¬¦ä¸²å¨ str ä¸ç¬¬ä¸æ¬¡åºç°çä½ç½®
System.out.println(index); // è¾åº 3â£ãç¤ºä¾ 4ï¼æ¥æ¾å¤ä¸ªåå符串
String str = "Hello, world!";
int index1 = str.indexOf("o"); // æ¥æ¾ "o" ååç¬¦ä¸²å¨ str ä¸ç¬¬ä¸æ¬¡åºç°çä½ç½®
int index2 = str.indexOf("o", 5); // ä»ç´¢å¼ä¸º5çä½ç½®å¼å§æ¥æ¾ "o" ååç¬¦ä¸²å¨ str ä¸ç¬¬ä¸æ¬¡åºç°çä½ç½®
System.out.println(index1); // è¾åº 4
System.out.println(index2); // è¾åº 8String ç±»çå ¶ä»æ¹æ³
â ãæ¯å¦è¯´ length() ç¨äºè¿åå符串é¿åº¦ã
â¡ãæ¯å¦è¯´ isEmpty() ç¨äºå¤æå符串æ¯å¦ä¸ºç©ºã
â¢ãæ¯å¦è¯´ charAt() ç¨äºè¿åæå®ç´¢å¼å¤çå符ã
â£ãæ¯å¦è¯´ valueOf() ç¨äºå°å
¶ä»ç±»åçæ°æ®è½¬æ¢ä¸ºå符串ã
String str = String.valueOf(123); // å°æ´æ° 123 转æ¢ä¸ºå符串valueOf æ¹æ³çèåå ¶å®è°ç¨çæ¯å è£ å¨ç±»ç toString æ¹æ³ï¼æ¯å¦è¯´æ´æ°è½¬ä¸ºå符串è°ç¨çæ¯ Integer ç±»ç toString æ¹æ³ã
public static String valueOf(int i) {
return Integer.toString(i);
}è Integer ç±»ç toString æ¹æ³åè°ç¨äº Integer ç±»çéææ¹æ³ toString(int i)ï¼
public static String toString(int i) {
// æå°å¼è¿å "-2147483648"
if (i == Integer.MIN_VALUE)
return "-2147483648";
// æ´æ°çé¿åº¦ï¼è´æ°çé¿åº¦å 1
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
// ææ´æ°å¤å¶å°å符æ°ç»ä¸
char[] buf = new char[size];
// å
·ä½çå¤å¶è¿ç¨
getChars(i, size, buf);
// éè¿ new è¿åå符串
return new String(buf, true);
}è³äº getChars æ¹æ³ï¼å°±æ¯ææ´æ°å¤å¶å°å符æ°ç»ä¸çå ·ä½è¿ç¨äºï¼è¿éå°±ä¸å±å¼äºã
â¥ãæ¯å¦è¯´ getBytes() ç¨äºè¿åå符串çåèæ°ç»ï¼å¯ä»¥æå®ç¼ç æ¹å¼ï¼æ¯å¦è¯´ï¼
String text = "æ²é»çäº";
System.out.println(Arrays.toString(text.getBytes(StandardCharsets.UTF_8)));â¦ãæ¯å¦è¯´ trim() ç¨äºå»é¤å符串两侧ç空ç½åç¬¦ï¼æ¥çæºç ï¼
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}举ä¾ï¼" æ²é»çäº ".trim() ä¼è¿å"æ²é»çäº"
â§ãæ¯å¦è¯´ toCharArray() ç¨äºå°å符串转æ¢ä¸ºå符æ°ç»ã
String text = "æ²é»çäº";
char[] chars = text.toCharArray();
System.out.println(Arrays.toString(chars));餿¤ä¹å¤ï¼è¿æ splitãequalsãjoin çè¿äºæ¹æ³ï¼æä»¬åé¢ä¼ä¸ä¸æ¥ç»è®²ã
å°ç»
å¦å®è¿ä¸èï¼å ¶å®å¯ä»¥æ¿ LeetCode ç第ä¸éé¢ãæ éå¤å符çæé¿åä¸²ãæ¥ç»æï¼ä½ å¯ä»¥éè¿æ´åçæ¹å¼ï¼ä¹å°±æ¯ä¸¤ä¸ª for å¾ªç¯æ¥è§£å³ã
å½ç¶äºï¼å¦æå®å¨è§£ä¸åºæ¥ï¼é¢è§£ææ¾å°äºææ¯æ´¾çãäºå¥ç LeetCode å·é¢ç¬è®°ãå½ä¸ï¼ä½ å¯ä»¥å»åèãæ¯å¯¹å符串å for 循ç¯ç䏿¬¡å¾å¥½çç»ä¹ ã
GitHub 䏿 æ 10000+ ç弿ºç¥è¯åºãäºå¥ç Java è¿é¶ä¹è·¯ã第ä¸ç PDF ç»äºæ¥äºï¼å æ¬ Java åºç¡è¯æ³ãæ°ç»&å符串ãOOPãéåæ¡æ¶ãJava IOãå¼å¸¸å¤çãJava æ°ç¹æ§ãç½ç»ç¼ç¨ãNIOãå¹¶åç¼ç¨ãJVM ççï¼å ±è®¡ 32 ä¸ä½åï¼500+å¼ æç»å¾ï¼å¯ä»¥è¯´æ¯éä¿ææãé£è¶£å¹½é»â¦â¦è¯¦æ æ³ï¼å¤ªèµäºï¼GitHub 䏿 æ 10000+ ç Java æç¨
å¾®ä¿¡æ æ²é»çäº ææ«æä¸æ¹äºç»´ç å ³æ³¨äºå¥çååå ¬ä¼å·æ²é»çäºï¼åå¤ 222 å³å¯å è´¹é¢åã

