Java源码解析|String源码与常用方法
String源码与常用方法1.栗子代码: public class JavaStringClass { public static void main(String[] args) { String s ="hello"; s = "world"; //内存地址已经修改 原来地址上的值还是不变的 String s2 = "hello"; //从常量值中找到并引用 String s4 = new String("hello"); //new产生一个新的对象 不会从常量池中引用 String s6 = "hel" + "lo"; String s7 = new String("hel") + new String("lo"); System.out.println(s == s2); //引用相等 System.out.println(s2 == s4); //引用不相等 System.out.println(s2.equals(s4)); //值相等 分析equals方法源码 System.out.println(s2 == s6); //引用相等 使用相 常量相加 也是从常量池中找到引用 System.out.println(s2 == s7); //引用不相等 //开头字母大写 System.out.println(s2.substring(0,1).toUpperCase() + s2.substring(1)); System.out.println(s2); } } 输出: 2.String的不变性2-1:字符串常量池 String s ="hello"; String s2 = "hello"; System.out.println(s == s2); //true 说明引用相等(地址相等) `s与s2引用相等即地址相等,原因是:Java把字符串常量存入字符串常量池 而 String s4 = new String("hello"); s4和 s2的值不相等,是因为new会产生一个新的对象,不会从字符串常量池中找引用 2-2:String的不变性 `主要是因为 String 和保存数据的 char 数组,都被 final 关键字所修饰,所以是不可变的 如下图所示:被final关键字修饰的变量(这里是字符数组),值不可以改变 所以当 String s ="hello"; s = “world”时,s的内存地址(s的引用对象)已经改变了, 3.String重写equal方法,判断相等
public boolean equals(Object anObject) { // 判断内存地址是否相同 if (this == anObject) { return true; } // 待比较的对象是否是 String,如果不是 String,直接返回不相等 if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; // 两个字符串的长度是否相等,不等则直接返回不相等 if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; // 依次比较每个字符是否相等,若有一个不等,直接返回不相等 while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; } 4.String常用的操作方法4-1:字符串截取: 4-2:字符串大小写: 上面两种常用方法的综合应用:将首字母小写 name.substring(0,1).toLowerCase() name.substring(1); 4-3:字符串替换、删除 public void testReplace(){ String str ="hello word !!"; log.info("替换之前 :{}",str); str = str.replace('l','d'); log.info("替换所有字符 :{}",str); str = str.replaceAll("d","l"); log.info("替换全部 :{}",str); str = str.replaceFirst("l",""); log.info("替换第一个 l :{}",str); } //输出的结果是: 替换之前 :hello word !! 替换所有字符 :heddo word !! 替换全部 :hello worl !! 替换第一个 :helo worl !! 4-4:字符串拆分 String s ="boo:and:foo"; // 我们对 s 进行了各种拆分,演示的代码和结果是: s.split(":") 结果:["boo","and","foo"] s.split(":",2) 结果:["boo","and:foo"] s.split(":",5) 结果:["boo",-2) 结果:["boo","foo"] s.split("o") 结果:["b","",":and:f"] s.split("o",2) 结果:["b","o:and:foo"] 但是会拆分出空值 String a =",a,b,"; a.split(",") 结果:["","a","b"] 使用google的Guava快速去除空值 String a =",b c,"; // Splitter 是 Guava 提供的 API List<String> list = Splitter.on(',') .trimResults()// 去掉空格 .omitEmptyStrings()// 去掉空值 .splitToList(a); log.info("Guava 去掉空格的分割方法:{}",JSON.toJSONString(list)); // 打印出的结果为: ["a","b c"] 4-5:字符串合并 合并我们使用 join 方法,此方法是静态的,我们可以直接使用。 不足:join不能连续合并(不能链式合并),无法过滤Join对象是List时的null值 解决办法:使用Guava 提供的 API,Joiner快速合并 // 依次 join 多个字符串,Joiner 是 Guava 提供的 API Joiner joiner = Joiner.on(",").skipNulls(); String result = joiner.join("hello",null,"china"); log.info("依次 join 多个字符串:{}",result); List<String> list = Lists.newArrayList(new String[]{"hello","china",null}); log.info("自动删除 list 中空值:{}",joiner.join(list)); // 输出的结果为; 依次 join 多个字符串:hello,china 自动删除 list 中空值:hello,china (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |