String本质是对char数组的封装
Serializable接口
实现Serializable接口的类可以被序列化
Comparable接口
实现Comparable接口的类可以支持排序,需要重写的compareTo方法返回两个字符串中第一个不同的字符的ASCII码差值
CharSequence接口
多态,String、StringBuffer及StringBuilder均实现了CharSequence接口,可以减少传参时的类型转换
String私有变量
1 /* 2 1.char value[]表明String实质是以字符数组的形式存放的 3 2.final关键字表明String一旦创建就无法改变,对于String 4 的重新赋值都是重新划分内存空间,创建了新的String 5 */ 6 private final char value[]; 7 8 //缓存String的hashCode值 默认为0 9 private int hash;
String构造函数
1 public class Demo1 { 2 public static void main(String[] args) throws Exception { 3 String str1 = "abcd"; 4 System.out.println(str1);// abcd 5 6 String str2 = new String(); 7 System.out.println(str2);// 8 9 String str3 = new String("abcd"); 10 System.out.println(str3);// abcd 11 12 char[] c = { 'a', 'b', 'c', 'd', 'e', 'f' }; 13 String str4 = new String(c); 14 System.out.println(str4);// abcdef 15 String str5 = new String(c, 2, 3); 16 System.out.println(str5);// cde 17 18 int[] a = { 65, 66, 67, 68, 97, 98 }; 19 String str6 = new String(a, 2, 3); 20 System.out.println(str6);// CDa 21 22 byte[] b = { 65, 66, 67, 68 }; 23 String str7 = new String(b, 1, 3, "ASCII"); 24 System.out.println(str7);// BCD 25 String str8 = new String(b, 1, 3); 26 System.out.println(str8);// BCD 27 String str9 = new String(b, "ASCII"); 28 System.out.println(str9);// ABCD 29 String str10 = new String(b); 30 System.out.println(str10);// ABCD 31 32 StringBuffer sb1 = new StringBuffer("abcd"); 33 String str11 = new String(sb1); 34 System.out.println(str11);// abcd 35 36 StringBuilder sb2 = new StringBuilder("abcde"); 37 String str12 = new String(sb2); 38 System.out.println(str12);// abcde 39 } 40 }
String核心方法
1 import java.util.Date; 2 public class Demo2 { 3 public static void main(String[] args) throws Exception { 4 String str1 = "abcde"; 5 System.out.println(str1.length());// 5 返回String的长度 6 System.out.println(str1.isEmpty());// false 判断String是否为空 7 System.out.println(str1.charAt(1));// b 返回value[index] 8 System.out.println(str1.codePointAt(1));// 98 9 System.out.println(str1.codePointBefore(1));// 97 10 /* 11 Java中超出char编码范围(65536)的unicode字符由两个char组成 12 codePointCount()是准确计算unicode(而不是char)字符的数量的方法 13 */ 14 System.out.println(str1.codePointCount(1, 3));// 2 返回1-3之间的码点值 15 System.out.println(str1.offsetByCodePoints(1, 3));// 4 返回从1偏移3个码点后的索引 16 char[] c = new char[10]; 17 str1.getChars(0, 3, c, 0);// 把value[0-3)的值复制到c中(从0开始存放) 18 for (char d : c) { 19 System.out.print(d + " ");// a b c 20 } 21 System.out.println(); 22 byte[] b1 = str1.getBytes("ASCII"); 23 for (byte b : b1) { 24 System.out.print(b + " ");// 97 98 99 100 101 25 } 26 System.out.println(); 27 byte[] b2 = str1.getBytes(); 28 for (byte b : b2) { 29 System.out.print(b + " ");// 97 98 99 100 101 30 } 31 System.out.println(); 32 System.out.println(str1.equals("abc"));//false 33 System.out.println(str1.contentEquals(new StringBuffer("abcde")));//true 34 System.out.println(str1.contentEquals(new StringBuilder("ABCDE")));//false 35 System.out.println(str1.equalsIgnoreCase("ABCDE"));//true 36 String str3 = "abcdE"; 37 System.out.println(str1.compareTo(str3));// 32 e-E 38 System.out.println(str1.compareToIgnoreCase(str3));// 0 39 System.out.println(str1.compareTo("abcdefg"));// -2 5-7 40 System.out.println(str1.compareToIgnoreCase("abcdefg"));// -2 41 System.out.println(str1.regionMatches(0, str3, 0, str3.length()));//false 42 System.out.println(str1.regionMatches(true, 0, str3, 0, str3.length()));//true 43 System.out.println(str1.startsWith("bc", 1));//true 44 System.out.println(str1.startsWith("ab"));//true 45 System.out.println(str1.endsWith("de"));//true 46 /* 47 3105 31*(31*0+97)+98 48 实际上ab的hashCode值就是把ab从31进制转化为10进制的值 49 */ 50 System.out.println("ab".hashCode()); 51 System.out.println("abacd".indexOf(97));// 0 52 System.out.println("abcd".indexOf(99, 2));// 2 53 System.out.println("abababa".lastIndexOf(97));// 6 54 System.out.println("aba".lastIndexOf(98, 0));// -1 55 System.out.println("aababcabcd".indexOf("abcd"));// 6 56 System.out.println("aababcabcdabcd".indexOf("abcd", 7));// 10 57 System.out.println("ababab".lastIndexOf("ab"));// 4 58 System.out.println("ababab".lastIndexOf("ab", 5));// 4 59 System.out.println("ababab".lastIndexOf("ab", 4));// 4 60 System.out.println("ababab".lastIndexOf("ab", 3));// 2 61 System.out.println(str1.substring(2));// cde 62 System.out.println(str1.substring(1, 3));// bc 63 System.out.println(str1.subSequence(1, 3));// bc 64 System.out.println("to".concat("get").concat("her"));// together 65 System.out.println("ababab".replace('b', 'c'));// acacac 66 System.out.println(str1.matches("([a-zA-Z])+"));// true 67 System.out.println("aababcabcd".contains("ab"));// true 68 System.out.println("aababcabcd".replaceFirst("[a][b]", "AC"));// aACabcabcd 69 System.out.println("aababcabcd".replaceAll("[a][b]", "AC"));// aACACcACcd 70 System.out.println("aababcabcd".replace("ab", "AC"));// aACACcACcd 71 String[] s1 = "boo:and:foo".split(":", 2); 72 for (String string : s1) { 73 System.out.print(string + " ");// boo and:foo n>0 pattern模式执行n-1次 74 } 75 System.out.println(); 76 String[] s2 = "boo:and:foo".split(":", -2); 77 for (String string : s2) { 78 System.out.print(string + " ");// boo and foo n<0 pattern模式执行无限次 79 } 80 System.out.println(); 81 String[] s3 = "boo:and:foo".split("o", -2); 82 for (String string : s3) { 83 System.out.print(string + " ");// b :and:f 84 } 85 System.out.println(); 86 String[] s4 = "boo:and:foo".split("o", 0); 87 for (String string : s4) { 88 // b :and:f n=0 pattern模式执行无限次并省略末尾的空字符串 89 System.out.print(string + " "); 90 } 91 System.out.println(); 92 String[] s5 = "boo:and:foo".split("o"); 93 for (String string : s5) { 94 System.out.print(string + " ");// b :and:f 95 } 96 System.out.println(); 97 System.out.println("abcde".toUpperCase());// ABCDE 98 System.out.println("Abcd".toLowerCase());// abcd 99 System.out.println(" a bc de ".trim());// a bc de 100 char[] c2 = str1.toCharArray(); 101 for (char d : c2) { 102 System.out.print(d + " ");// a b c d e 103 } 104 System.out.println(); 105 System.out.println(String.format("%tF", new Date()));// 2017-12-04 106 String str6 = null; 107 // System.out.println(str6.toString()); //NullPointerException 108 System.out.println(String.valueOf(str6));// null 109 } 110 }
join
1 import java.util.ArrayList; 2 import java.util.List; 3 import org.junit.Test; 4 public class Demo3 { 5 @Test 6 public void fun1() { 7 System.out.println(String.join("-", "java", "is", "cool"));// java-is-cool 8 List<String> list = new ArrayList<String>(); 9 list.add("java"); 10 list.add("is"); 11 list.add("cool"); 12 System.out.println(String.join(" ", list));// java is cool 13 } 14 }
部分方法源码分析
equals
1 public boolean equals(Object anObject) { 2 //1.判断是否==,是就直接返回true(==的要求比equals更加严格) 3 if (this == anObject) { 4 return true; 5 } 6 //2.判断anObject是否为String,是就接着判断,否则返回false 7 if (anObject instanceof String) { 8 String anotherString = (String)anObject; 9 int n = value.length; 10 //3.判断二者长度是否一样,是就接着判断,否则返回false 11 if (n == anotherString.value.length) { 12 char v1[] = value; 13 char v2[] = anotherString.value; 14 int i = 0; 15 //4.依次比较所有元素,全部一样返回true,否则返回false 16 while (n-- != 0) { 17 if (v1[i] != v2[i]) 18 return false; 19 i++; 20 } 21 return true; 22 } 23 } 24 return false; 25 }
compareTo
1 public int compareTo(String anotherString) { 2 int len1 = value.length; 3 int len2 = anotherString.value.length; 4 //1.得到两个字符串长度的最小值lim 5 int lim = Math.min(len1, len2); 6 char v1[] = value; 7 char v2[] = anotherString.value; 8 int k = 0; 9 /* 10 2.在0-lim范围内依次比较所有元素返回 11 第一个不相同的char的差值(如果有的话) 12 */ 13 while (k < lim) { 14 char c1 = v1[k]; 15 char c2 = v2[k]; 16 if (c1 != c2) { 17 return c1 - c2; 18 } 19 k++; 20 } 21 //3.否则返回字符串长度的差值 22 return len1 - len2; 23 }
startsWith
1 public boolean startsWith(String prefix, int toffset) { 2 char ta[] = value; 3 int to = toffset; 4 char pa[] = prefix.value; 5 int po = 0; 6 int pc = prefix.value.length; 7 //1.检查边界 8 if ((toffset < 0) || (toffset > value.length - pc)) { 9 return false; 10 } 11 //2.从to开始依次比较pc次,出现一次不一样返回false,否则返回true 12 while (--pc >= 0) { 13 if (ta[to++] != pa[po++]) { 14 return false; 15 } 16 } 17 return true; 18 }
indexOf
1 public int indexOf(String str, int fromIndex) { 2 return indexOf(value, 0, value.length, 3 str.value, 0, str.value.length, fromIndex); 4 } 5 6 static int indexOf(char[] source, int sourceOffset, int sourceCount, 7 char[] target, int targetOffset, int targetCount, 8 int fromIndex) { 9 if (fromIndex >= sourceCount) { 10 return (targetCount == 0 ? sourceCount : -1); 11 } 12 if (fromIndex < 0) { 13 fromIndex = 0; 14 } 15 if (targetCount == 0) { 16 return fromIndex; 17 } 18 19 char first = target[targetOffset]; 20 int max = sourceOffset + (sourceCount - targetCount); 21 22 for (int i = sourceOffset + fromIndex; i <= max; i++) { 23 if (source[i] != first) { 24 while (++i <= max && source[i] != first); 25 } 26 27 if (i <= max) { 28 int j = i + 1; 29 int end = j + targetCount - 1; 30 for (int k = targetOffset + 1; j < end && source[j] 31 == target[k]; j++, k++); 32 33 if (j == end) { 34 return i - sourceOffset; 35 } 36 } 37 } 38 return -1; 39 }
replace
1 public String replace(char oldChar, char newChar) { 2 //1.判断oldChar和newChar是否一样,是就返回this 3 if (oldChar != newChar) { 4 int len = value.length; 5 int i = -1; 6 char[] val = value; 7 //2.找到第一个是oldChar的索引i 8 while (++i < len) { 9 if (val[i] == oldChar) { 10 break; 11 } 12 } 13 if (i < len) { 14 char buf[] = new char[len]; 15 //3.复制i之前的元素到buf中 16 for (int j = 0; j < i; j++) { 17 buf[j] = val[j]; 18 } 19 //4.对i以及i之后的元素进行替换 20 while (i < len) { 21 char c = val[i]; 22 buf[i] = (c == oldChar) ? newChar : c; 23 i++; 24 } 25 return new String(buf, true); 26 } 27 } 28 return this; 29 }
split
1 public String[] split(String regex, int limit) { 2 char ch = 0; 3 if (((regex.value.length == 1 && 4 ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || 5 (regex.length() == 2 && 6 regex.charAt(0) == '\\' && 7 (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 && 8 ((ch-'a')|('z'-ch)) < 0 && 9 ((ch-'A')|('Z'-ch)) < 0)) && 10 (ch < Character.MIN_HIGH_SURROGATE || 11 ch > Character.MAX_LOW_SURROGATE)) 12 { 13 int off = 0; 14 int next = 0; 15 boolean limited = limit > 0; 16 ArrayList<String> list = new ArrayList<>(); 17 while ((next = indexOf(ch, off)) != -1) { 18 if (!limited || list.size() < limit - 1) { 19 list.add(substring(off, next)); 20 off = next + 1; 21 } else { 22 list.add(substring(off, value.length)); 23 off = value.length; 24 break; 25 } 26 } 27 if (off == 0) 28 return new String[]{this}; 29 if (!limited || list.size() < limit) 30 list.add(substring(off, value.length)); 31 int resultSize = list.size(); 32 if (limit == 0) { 33 while (resultSize > 0 && list.get(resultSize - 1).length() == 0) { 34 resultSize--; 35 } 36 } 37 String[] result = new String[resultSize]; 38 return list.subList(0, resultSize).toArray(result); 39 } 40 return Pattern.compile(regex).split(this, limit); 41 }
trim
1 public String trim() { 2 int len = value.length; 3 int st = 0; 4 //可以提高性能 5 char[] val = value; 6 //1.从左向右遍历空白,得到第一个不是空白的索引st 7 while ((st < len) && (val[st] <= ' ')) { 8 st++; 9 } 10 //2.从右向左遍历空白,得到最后一个空白的索引len 11 while ((st < len) && (val[len - 1] <= ' ')) { 12 len--; 13 } 14 //3.通过substring(st,len)返回结果 15 return ((st > 0) || (len < value.length)) ? substring(st, len) : this; 16 }
intern
1 /* 2 A native method is a Java method whose implementation is provided by non-java code 3 在Java中,用双引号声明出来的String对象会直接存储在常量池中,如果不是用双引号声明的String对象,可 4 以用String提供的intern方法。intern方法会从字符串常量池中查询当前字符串是否存在,若不存在就会把 5 当前字符串放入常量池中,再返回。 6 */ 7 public native String intern();