概要
String 属于引用类型,不属于基本类型
用双引号括起来的字符串,例如“abs”,”def”都是存储在“方法区”的“字符串常量池”中
使用“+”进行字符串拼接,如String s = “a”+“b”,会在方法去产生两个字符串对象,在堆内存中产生一个String s对象,频繁使用导致内存空间的浪费
面试题:String为什么是不可变的? 我看过源代码,String类中有一个byte[ ]数组,这个byte[ ]数组采用了final修饰,因为数组一旦创建长度不可变。并且被final修饰的引用一旦指向某个对象之后,不可再指向其它对象,所以String是不可变的! "abc”无法变成"abcd"
StringBuiLder/StringBuffer为什么是可变的呢? 我看过源代码,StringBuffer/StringBuiLder内部实际上是一个byte[ ]数组,这个byte[ ]数组没有披final修饰,StringBuffer/StringBuilder的初始化容量我记得应该是16,当存满之后会进行扩容,底层调用了数组拷贝的方法System.arraycopy()…是这样扩容的。所以stringBuilder/StringBuffer适合于使用字符串的频繁拼接操作。
String字符串的存储原理 01 这里本该有一张图
1 2 3 4 5 6 7 8 9 10 11 12 13 public class _425_String 字符串的存储原理 { public static void main (String[] args) { String s1 = "abcdef" ; String s2 = "abcdef" + "xy" ; String s3 = new String("xy" ); } }
02 这里本该有一张图
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 public class _426_String 字符串的存储原理 { public static void main (String[] args) { User user = new User(110 , "张三" ); String s1 = "hello" ; String s2 = "hello" ; System.out.println(s1 == s2); String x = new String("xyz" ); String y = new String("xyz" ); System.out.println(x == y); System.out.println(x.equals(y)); System.out.println("xyz" .equals(x)); } } class User { int Id; String name; public User (int id, String name) { Id = id; this .name = name; } }
03 1 2 3 4 5 6 7 8 9 10 11 12 13 public class _428_String 面试题中创建了几个对象 { public static void main (String[] args) { String s1 = new String("hello" ); String s2 = new String("hello" ); } }
String类的构造方法 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 public class _429_String 类的构造方法 { public static void main (String[] args) { String s = new String("hello" ); System.out.println(s); String s1 = "abc" ; System.out.println(s1); byte [] bytes = {97 ,98 ,99 }; String s2 = new String(bytes); System.out.println(s2); String s3 = new String(bytes,1 ,2 ); System.out.println(s3); char [] chars = {'a' ,'b' ,'c' ,'d' ,'e' }; String s4 = new String(chars); System.out.println(s4); String s5 = new String(chars,2 ,3 ); System.out.println(s5); } }
String类中的方法 charAt() 1 2 3 4 5 6 7 public class _430_String 类的charAt 方法 { public static void main (String[] args) { char c = "abc" .charAt(2 ); System.out.println(c); } }
compareTo() 按照字典序比较大小 相等返回0 小返回负数 大返回正数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class _431_String 类的compareTo 方法 { public static void main (String[] args) { int res = "abc" .compareTo("abc" ); System.out.println(res); int res1 = "abc" .compareTo("abcd" ); System.out.println(res1); int res2 = "abc" .compareTo("ac" ); System.out.println(res2); int res3 = "abc" .compareTo("cba" ); System.out.println(res3); int res4 = "abc" .compareTo("aba" ); System.out.println(res4); } }
contains() 判断是否包含字符串
1 2 3 4 5 6 7 public class _432_String 类的contains 方法 { public static void main (String[] args) { System.out.println("hello" .contains("ell" )); } }
endsWith() 判断当前字符串是否以某字符串结尾
1 2 3 4 5 6 7 public class _433_String 类的endsWith 方法 { public static void main (String[] args) { System.out.println("t1.txt" .endsWith(".txt" )); } }
equals()和compareTo() 在Java8中equals()代码中不包含compareTo()…
equalsIgnoreCase() 就是忽略大小写的equals()
1 2 3 4 5 6 public class _437_String 类的equalsIgnoreCase 方法 { public static void main (String[] args) { System.out.println("abc" .equalsIgnoreCase("ABC" )); } }
getBytes() 就是将字符串转换为byte数组
1 2 3 4 5 6 7 8 9 public class _438_String 类的getBytes 方法 { public static void main (String[] args) { byte [] bytes = "ans" .getBytes(); for (int i = 0 ; i < bytes.length; i++) { System.out.println(bytes[i]); } } }
indexOf() 返回字符串第一次出现起始位置的下标
1 2 3 4 5 6 7 8 public class _438_String 类的getBytes 方法 { public static void main (String[] args) { System.out.println("abcabcac" .indexOf("ca" )); } }
isEmpty() 判断是否为空串 不能 String s = null 会空指针异常
1 2 3 4 5 6 7 8 9 public class _439_String 类的isEmpty 方法 { public static void main (String[] args) { String s = "" ; System.out.println(s.isEmpty()); String s1 = "11" ; System.out.println(s1.isEmpty()); } }
lastIndexOf() 返回字符串最后一次出现的索引
1 2 3 4 5 6 public class _440_String 类的replace 方法 { public static void main (String[] args) { System.out.println("abcabcac" .lastIndexOf("ca" )); } }
replace() 将“ab”->“xx”
1 2 3 4 5 6 7 8 public class _440_String 类的replace 方法 { public static void main (String[] args) { System.out.println("abaabc" .replace("ab" ,"xx" )); } }
split() 拆分…
1 2 3 4 5 6 7 8 9 10 public class _440_String 类的replace 方法 { public static void main (String[] args) { String[] s = "2001-1-24" .split("-" ); for (int i = 0 ; i < s.length; i++) { System.out.println(s[i]); } } }
startsWith() 判断是否为某字符串开头
1 2 3 4 5 6 public class _441_String 类的substring 方法 { public static void main (String[] args) { System.out.println("abc" .startsWith("ab" )); } }
substring() 截取子字符串
1 2 3 4 5 6 7 8 9 public class _441_String 类的substring 方法 { public static void main (String[] args) { String s = "abcde" .substring(3 ); System.out.println(s); String s1 = "abcde" .substring(2 ,4 ); System.out.println(s1); } }
toCharArray() 转化为char数组
1 2 3 4 5 6 7 8 9 public class _442_String 类的toCharArray 方法 { public static void main (String[] args) { char [] chars = "abc" .toCharArray(); for (int i = 0 ; i < chars.length; i++) { System.out.println(chars[i]); } } }
toLowerCase() 与 toUpperCase() 大小写转化
1 2 3 4 5 6 7 public class _443_String 类的toLowerCase 方法 { public static void main (String[] args) { System.out.println("ABC" .toLowerCase()); System.out.println("abc" .toUpperCase()); } }
trim() 取出字符串前后空白
1 2 3 4 5 6 public class _444_String 类的valueOf 方法 { public static void main (String[] args) { System.out.println(" abc " .trim()); } }
valueOf() String类方法中 只有一个 valueOf 方法是静态的 不需要 new 对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class _444_String 类的valueOf 方法 { public static void main (String[] args) { String s = String.valueOf(97 ); System.out.println(s); String s1 = String.valueOf(new Customer()); System.out.println(s1); } } class Customer {}
StringBuffer 使用“+”进行字符串拼接,如String s = “a”+“b”,会在方法去产生两个字符串对象,在堆内存中产生一个String s对象,频繁使用导致内存空间的浪费
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 public class _445_StringBuffer 进行字符串拼接 { public static void main (String[] args) { String s1 = "" ; for (int i = 0 ; i < 100 ; i++) { s1 += i; } StringBuffer s2 = new StringBuffer(); s2.append("a" ); s2.append(3.14 ); s2.append(true ); System.out.println(s2); StringBuffer s3 = new StringBuffer(10 ); s3.append("heooolo" ); System.out.println(s3); s3.append("xxxxxxxx" ); System.out.println(s3); } }
StringBuilder和StringBuffer的区别 StringBuffer中的方法都有:synchronized 关键词修饰,表示StringBuffer在多线程环境下时安全的 StringBuilder是非线程安全的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class _446_StringBuilder 和StringBuffer 的区别 { public static void main (String[] args) { StringBuilder s1 = new StringBuilder(); s1.append("abc" ); s1.append(true ); s1.append(3.456 ); System.out.println(s1); } }