本文是系列文章的第二篇,主要讲述的是
- String的hashCode
- 字符串的拼接。
- 流与字符集的转换
- codePointAt 用法
首先说说String的hashCode 计算办法:
我们知道Integer的hashCode就是数值本身,那么字符串类型的如何计算的呢?
源码中注释已经说明了他的算法:
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
同时代码也已经给出了实现,这里的^符号表示的幂,而不是异或运算符号。
字符串的拼接
String中已经提供了concat 的的办法,同时也可以使用+符号进行计算。他们的区别究竟在哪里?
首先看看concat:代码如下
char buf[] = Arrays.copyOf(value, len + otherLen); // 申请数组 长度等于两个字符串的和 str.getChars(buf, len); // 把第二个字符串的内容填充到数组中。 return new String(buf, true);// 创建新的字符串中并返回。
而使用+ 的形式则不是这样的,它借助了StringBuilder的类。参照例子如下代码
String s1="12";
String s2="34";
String ss = s1+s2;
在执行第三行的时候,实际上是使用了两次StringBuilder的append 。过程是先隐式的创建StringBuilder对象,此时对象是空的,调用 append函数,此时参数内容是“12”,接下来再次执行append函数,参数是“34”,最后执行一次toString方法。
byte bytes[] 与String的转换。
字节数组中每个字节占8位,用于表达英文字符以及数字等符号是足够使用的,但是世界有各种各样的语言,字符种类很多,如何用字节流表达各种各样的字符呢,这就引入了字符集的概念。同样的字节流在不同字符集下所表示的符号是不同的,所以字符串与bytes进行相互转换的时候需要指定字符集。
String的encode 和decode方法实际上都借助了StringCoding工具类,使用该工具类在没有指定字符集的情况下,默认使用ISO-8859-1字符集。
参见构造函数 String(byte bytes[], int offset, int length, Charset charset) 即可。
codePointAt 用法:
这里返回的是一个int类型,大家知道字符串实际上由Char类型组成,而无符号的char取值范围是0--65536.而字符串需要表达复杂符号的时候需要两个字符甚至三个字节来表达,而使用本方法就可以完整的获得复杂符号的具体的整数数值。他的算法是先得到该位置上的char类型的数值,然后在获取其下一个位置上的char类型数值,如果下一个元素的数值介于'\uDC00' 和 '\uDFFF'之间则将这两个char数值进行运算,运算规则是(
((high - MIN_HIGH_SURROGATE) << 10) // + (low - MIN_LOW_SURROGATE) // + MIN_SUPPLEMENTARY_CODE_POINT;
) 得到一个整型值返回,否则直接返回当前位置上的元素的数值。