java.lang.string源码_JDK1.8源码——java.lang.String 类

String 类也是java.lang 包下的一个类,算是日常编码中最常用的一个类了,那么本篇博客就来详细的介绍 String 类。

1、String 类的定义

public final class String

implements java.io.Serializable, Comparable, CharSequence {}

和上一篇博客所讲的 Integer 类一样,这也是一个用 final 声明的常量类,不能被任何类所继承,而且一旦一个String对象被创建, 包含在这个对象中的字符序列是不可改变的, 包括该类后续的所有方法都是不能修改该对象的,直至该对象被销毁,这是我们需要特别注意的(该类的一些方法看似改变了字符串,其实内部都是创建一个新的字符串,下面讲解方法时会介绍)。接着实现了 Serializable接口,这是一个序列化标志接口,还实现了 Comparable 接口,用于比较两个字符串的大小(按顺序比较单个字符的ASCII码),后面会有具体方法实现;最后实现了 CharSequence 接口,表示是一个有序字符的集合,相应的方法后面也会介绍。

2、字段属性

/**The value is used for character storage.*/

private final charvalue[];/**Cache the hash code for the string*/

private int hash; //Default to 0

/**use serialVersionUID from JDK 1.0.2 for interoperability*/

private static final long serialVersionUID = -6849794470754667710L;

一个 String 字符串实际上是一个 char 数组。

3、构造方法

String 类的构造方法很多。可以通过初始化一个字符串,或者字符数组,或者字节数组等等来创建一个 String 对象。

080f0d22ccdb3bb9fd2bb2d92501e0c0.png

String str1 = "abc";//注意这种字面量声明的区别,文末会详细介绍

String str2 = new String("abc");

String str3= new String(new char[]{'a','b','c'})

4、equals(Object anObject) 方法

instanceof运算符 用于:判断 该运算符前面引用类型变量指向的对象是否是后面类,或者其子类、接口实现类创建的对象。如果是则返回true,否则返回false,

其使用格式如下: 引用类型变量instanceof (类、抽象类或接口)

1 /**

2 * Compares this string to the specified object. The result is {@code

3 * true} if and only if the argument is not {@codenull} and is a {@code

4 * String} object that represents the same sequence of characters as this5 * object.6 *7 *@paramanObject8 * The object to compare this {@codeString} against9 *10 *@return{@codetrue} if the given object represents a {@codeString}11 * equivalent to this string, {@codefalse} otherwise12 *13 *@see#compareTo(String)14 *@see#equalsIgnoreCase(String)15 */

16 public booleanequals(Object anObject) {17 if (this ==anObject) {18 return true;19 }20 if (anObject instanceofString) {21 String anotherString =(String)anObject;22 int n =value.length;23 if (n ==anotherString.value.length) {24 char v1[] =value;25 char v2[] =anotherString.value;26 int i = 0;27 //比较每一个字符的值

28 while (n-- != 0) {29 if (v1[i] !=v2[i])30 return false;31 i++;32 }33 return true;34 }35 }36 return false;37 }

String 类重写了 equals 方法,比较的是组成字符串的每一个字符是否相同,如果都相同则返回true,否则返回false。

5、hashCode() 方法

1 /**

2 * Compares this string to the specified object. The result is {@code

3 * true} if and only if the argument is not {@codenull} and is a {@code

4 * String} object that represents the same sequence of characters as this5 * object.6 *7 *@paramanObject8 * The object to compare this {@codeString} against9 *10 *@return{@codetrue} if the given object represents a {@codeString}11 * equivalent to this string, {@codefalse} otherwise12 *13 *@see#compareTo(String)14 *@see#equalsIgnoreCase(String)15 */

16 public booleanequals(Object anObject) {17 if (this ==anObject) {18 return true;19 }20 if (anObject instanceofString) {21 String anotherString =(String)anObject;22 int n =value.length;23 if (n ==anotherString.value.length) {24 char v1[] =value;25 char v2[] =anotherString.value;26 int i = 0;27 while (n-- != 0) {28 if (v1[i] !=v2[i])29 return false;30 i++;31 }32 return true;33 }34 }35 return false;36 }

String 类的 hashCode 算法很简单,主要就是中间的 for 循环,计算公式如下:

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

s 数组即源码中的 val 数组,也就是构成字符串的字符数组。这里有个数字 31 ,为什么选择31作为乘积因子,而且没有用一个常量来声明?主要原因有两个:

①、31是一个不大不小的质数,是作为 hashCode 乘子的优选质数之一。

②、31可以被 JVM 优化,31 * i = (i << 5) - i。因为移位运算比乘法运行更快更省性能。

6.split(String regex) 和 split(String regex, int limit) 方法

split(String regex) 将该字符串拆分为给定正则表达式的匹配。split(String regex , int limit) 也是一样,不过对于 limit 的取值有三种情况:

①、limit > 0 ,则pattern(模式)应用n - 1 次

1 String str = "a,b,c";

2 String[] c1 = str.split(",", 2);

3 System.out.println(c1.length);//2

4 System.out.println(Arrays.toString(c1));//{"a","b,c"}

②、limit = 0 ,则pattern(模式)应用无限次并且省略末尾的空字串

1 String str2 = "a,b,c,,";

2 String[] c2 = str2.split(",", 0);

3 System.out.println(c2.length);//3

4 System.out.println(Arrays.toString(c2));//{"a","b","c"}

③、limit < 0 ,则pattern(模式)应用无限次

1 String str2 = "a,b,c,,";

2 String[] c2 = str2.split(",", -1);

3 System.out.println(c2.length);//5

4 System.out.println(Arrays.toString(c2));//{"a","b","c","",""}

下面我们看看底层的源码实现。对于 split(String regex) 没什么好说的,内部调用  split(regex, 0) 方法:

1 publicString[] split(String regex) {2 return split(regex, 0);3 }

重点看 split(String regex, int limit) 的方法实现:

1 public String[] split(String regex, intlimit) {2 /*1、单个字符,且不是".$|()[{^?*+\\"其中一个3 * 2、两个字符,第一个是"\",第二个大小写字母或者数字4 */

5 char ch = 0;6 if (((regex.value.length == 1 &&

7 ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||

8 (regex.length() == 2 &&

9 regex.charAt(0) == '\\' &&

10 (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&

11 ((ch-'a')|('z'-ch)) < 0 &&

12 ((ch-'A')|('Z'-ch)) < 0)) &&

13 (ch < Character.MIN_HIGH_SURROGATE ||

14 ch >Character.MAX_LOW_SURROGATE))15 {16 int off = 0;17 int next = 0;18 boolean limited = limit > 0;//大于0,limited==true,反之limited==false

19 ArrayList list = new ArrayList<>();20 while ((next = indexOf(ch, off)) != -1) {21 //当参数limit<=0 或者 集合list的长度小于 limit-1

22 if (!limited || list.size() < limit - 1) {23 list.add(substring(off, next));24 off = next + 1;25 } else {//判断最后一个list.size() == limit - 1

26 list.add(substring(off, value.length));27 off =value.length;28 break;29 }30 }31 //如果没有一个能匹配的,返回一个新的字符串,内容和原来的一样

32 if (off == 0)33 return new String[]{this};34

35 //当 limit<=0 时,limited==false,或者集合的长度 小于 limit是,截取添加剩下的字符串

36 if (!limited || list.size()

39 //当 limit == 0 时,如果末尾添加的元素为空(长度为0),则集合长度不断减1,直到末尾不为空

40 int resultSize =list.size();41 if (limit == 0) {42 while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {43 resultSize--;44 }45 }46 String[] result = newString[resultSize];47 return list.subList(0, resultSize).toArray(result);48 }49 return Pattern.compile(regex).split(this, limit);50 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值