String 类:(暂留:split()和replace()方法,以及new String(char[] a, boolean b) )
private final char value[];
String类中定义了一个私有的最终的char类型数组,
本质上就是把创建的String类型的字符串存进value[]数组中。
因为是final修饰,所以后面不可更改。
一.构造方法(new 初始化对象的时候使用)
1.public String(),初始化一个新创建的 String
对象,使其表示一个空字符序列。注意,由于 String 是不可变的,所以无需使用此构造方法。
2.public String(String str),丢一个String字符串,初始化一个新创建的String对象,使其表示一个与参数相同的字符序列。
String s = new String("abc");
源码:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
new一个String类对象,调用一个有参的构造函数把"abc"当作形参丢进去,
然后再把"abc"传进char类型数组value中
3.String(char[] cs),丢进去一个字符数组,初始化一个String对象。
char[] a = {'a','b','c','d','e'};
String s = new String(a);
源码:
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
由此可见,新创建的字符串是参数字符串的副本,
所以,随后的修改字符数组不会影响新创建的字符串。
4.String(char[] cs, int offset, int count
),丢进去一个字符数组和两个int类型常量,offset表示从字符数组的这个下标开始,count表示选中多少个字符,从而初始化一个String对象。(同理可以传入其他数组)
char[] a = {'a','b','c','d','e'};
String s = new String(a,1,2);
System.out.println(s);//bc
源码:
public String(char value[], int offset, int count) {
if (offset < 0) { //开始下标小于0,便会抛出异常
throw new StringIndexOutOfBoundsException(offset);
}
if (count <= 0) {
if (count < 0) { //复制的长度小于0,也会抛出异常
throw new StringIndexOutOfBoundsException(count);
}
if (offset <= value.length) { //复制的长度为0,并且开始下标不长于目标数组的长度
this.value = "".value;
return;
}
}
// Note: offset or count might be near -1>>>1.
// 注意:偏移量或计数可能接近-1>>>1。
if (offset > value.length - count) { //判断后面的内容够不够复制的
throw new StringIndexOutOfBoundsException(offset + count);
}
//都没有错才会把数组复制一份
this.value = Arrays.copyOfRange(value, offset, offset+count);
}
特殊的,当传入的数组为int类型时:
由于不是所有的Unicode字符都能用16bit(java中char是16bit)表示,
所以CodePoints参数为int数组,并且在构造函数中需要转换才能存入char value[] 中。
源码:
public String(int[] codePoints, int offset, int count) {
//这些都和前面一样,但是对于int类型数组,加了以下判断
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count <= 0) {
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
if (offset <= codePoints.length) {
this.value = "".value;
return;
}
}
// Note: offset or count might be near -1>>>1.
if (offset > codePoints.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
final int end = offset + count;//确定要复制到哪里
// Pass 1: Compute precise size of char[]
// 第1步:计算char[]的精确大小
int n = count; //接受复制之后数组的长度
for (int i = offset; i < end; i++) { //遍历将要复制的数组(不是全部,从要复制的开始)
int c = codePoints[i];
if (Character.isBmpCodePoint(c)) //传进的参数是否在Bmp中?
continue;
else if (Character.isValidCodePoint(c)) //传进的参数是否在Valid中?
n++; //如果是的就可以用一个char保存,否则要用两个
else throw new IllegalArgumentException(Integer.toString(c)); //不然就抛出异常
}
// Pass 2: Allocate and fill in char[]
// 第2步:分配和填充char[]
final char[] v = new char[n];
for (int i = offset, j = 0; i < end; i++, j++) {
int c = codePoints[i];
if (Character.isBmpCodePoint(c)) //只有数组中的内容(int)在Bmp中,才会复制
v[j] = (char)c;
else
Character.toSurrogates(c, v, j++);//如果不在,就调用toSurrogates方法
}
this.value = v;//因为是构造函数,所以要把结果返回给String类中定义的value数组
}
补充:
1个java的char字符并不完全等于一个unicode的字符。java只好对后来新增的unicode字符用2个char拼出1个unicode字符。导致String中char的数量不等于unicode字符的数量。
codePointCount()就是准确计算unicode字符的数量,而不是char的数量。
Character.isBmpCodePoint(c):编码点要测试的字符(Unicode编码点)
public static boolean isBmpCodePoint(int codePoint) {
return codePoint >>> 16 == 0;
//表示不带符号向右移动二进制数,移动后前面统统补0;两个箭头表示带符号移动
}
Character.isValidCodePoint(c):要测试的Unicode代码点
public static boolean isValidCodePoint(int codePoint) {
// Optimized form of:
// codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
int plane = codePoint >>> 16;
return plane < ((MAX_CODE_POINT + 1) >>> 16);
}
static void toSurrogates(int codePoint, char[] dst, int index) {
// We write elements "backwards" to guarantee all-or-nothing
//我们“向后”写入元素,以保证要么全有要么全无
dst[index+1] = lowSurrogate(codePoint);
dst[index] = highSurrogate(codePoint);
}
5.String(byte[] bs)和String(byte[] bs,int offset, int count
),同3,4一样,只是丢进去的数组不一样,根据ASCALL码变化。
byte[] a={97,98,99,100,101};
String s=new String(a);
String s1 = new String(a,1,2);
System.out.println(s);//abcde
System.out.println(s1);//bc
A:65 Z:90
a:97 z:122
6.String(byte[] bytes, String charsetname),丢进去一个byte数组和一个指定的charset解码去构建一个新的字符串对象。
二.常用的成员方法(使用字符串"."方法名调用)
注意:为方便对字符串处理,String 类提供了大量的方法。需要注意的是这些方法都不会对字符串本身做修改,而是返回处理结果,或者处理完成后,返回处理后的新字符串。
(这些方法有的会丢进去一个字符串,然后在底层会先转换成char类型数组,然后只要参与比较(大多数为循环),就要判断长度为负数,或者长度越界问题(底层实现了))
1.public int length(),返回调用此方法的字符串的长度。
String a="abcdef";
int length=a.length();
System.out.println(length); //6
源码:
public int length() {
return value.length;
}
数组中.length是属性,字符串中.length()是方法
2.public int indexOf(char c)// 返回c字符在字符串第一次出现的下标
public int indexOf(String c)// 返回字符串c在字符串第一次出现的下标
public int indexOf(String c,int fromIndex)// 返回字符串c在字符串在formIndex(包含)后第一次出现的下标
public int indexOf(char c,int fromIndex)// 返回字符c在字符串在formIndex(包含)后第一次出现的下标
String a = "abcdef123ghabcdef";
int indexOf = a.indexOf('d');
System.out.println(indexOf); //3
int indexOf2 = a.indexOf('d', 3); //3,看出来是包含传进去的这个形参的
System.out.println(indexOf2);
int indexOf3 = a.indexOf('d',4);
System.out.println(indexOf3); //14
int indexOf4 = a.indexOf("cde");
System.out.println(indexOf4); //2
int indexOf5 = a.indexOf("cde",3);
System.out.println(indexOf5); //13
注意:
1.丢进去的形参:fromIndex,是包含这个位置的,从这个位置开始,
2.数组是从0开始算起,不是1
3.此方法返回值不要忘记,记得要用一个int类型变量接受。
4.当查询的值在字符串中不存在的话,则返回-1
源码:(可以看出,底层都是参数少的方法在调用参数多的方法,即重载,提高了代码的可复用性)
public int indexOf(String str) {
return indexOf(str, 0);
}
public int indexOf(String str, int fromIndex) {
return indexOf(value, 0, value.length,
str.value, 0, str.value.length, fromIndex);
}
个形参的含义:
char[] source:源字符串(数组)
int sourceOffset:从源字符数组的哪个下标开始搜索
int sourceCount:源字符串(数组)的长度
char[] target:指定要搜索的字符,或者字符串(数组)
int targetOffset:从要搜索的字符串(数组)的下标(一般为0)
int targetCount:要搜索的字符串(数组)的长度(可定长)
int fromIndex:开始搜索的下标
static int indexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1); //返回-1表示没找到
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) { //要搜索数组长度为0
return fromIndex;
}
char first = target[targetOffset];//把要搜索的字符串(数组)的第一个字符提取出来
// 找到需要遍历的最大位置
int max = sourceOffset + (sourceCount - targetCount);
for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
// 找到第一个相等字符的位置,不相等就一直加,注意边界
if (source[i] != first) {
while (++i <= max && source[i] != first);
}
/* Found first character, now look at the rest of v2 */
// 找到第一个字符,现在看看v2的剩余部分
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
// 循环遍历,找到全部相同的
for (int k = targetOffset + 1; j < end && source[j]
== target[k]; j++, k++);
if (j == end) {
/* Found whole string. */ //找到这个字符串
return i - sourceOffset;
}
}
}
return -1;
}
例如:
String s = "97653287541";
String s1 = "287";
int indexOf = s.indexOf(s1);
s.indexOf(s1)-->s.indexOf(s1,0)-->s.indexOf(s,0,s.length(),s1,0,s1.length(),0)
其实好多参数都不是给这里用的。
3.public int lastIndexOf(char c);//判断字符c在字符串中最后一次出现的下标
public int lastIndexOf(String str);//判断字符串str在字符串中最后一次出现的下标
public int lastIndexOf(char ch, int fromIndex);//判断字符c在字符串从第fromIndex(包含)之前中最后一次出现的下标
public int lastIndexOf(String str, int fromIndex);//判断字符串str在字符串从第fromIndex(包含)之前中最后一次出现的下标
String a = "abcdef123ghabcdef";
int indexOf = a.lastIndexOf('d');
System.out.println(indexOf); //14
int indexOf2 = a.lastIndexOf('d', 3); //3
System.out.println(indexOf2);
int indexOf3 = a.lastIndexOf('d',4);
System.out.println(indexOf3); //3
int indexOf4 = a.lastIndexOf("cde");
System.out.println(indexOf4); //13
int indexOf5 = a.lastIndexOf("cde",3);
System.out.println(indexOf5); //2
源码:(没研究)
static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
/*
* Check arguments; return immediately where possible. For
* consistency, don't check for null str.
*/
int rightIndex = sourceCount - targetCount;
if (fromIndex < 0) {
return -1;
}
if (fromIndex > rightIndex) {
fromIndex = rightIndex;
}
/* Empty string always matches. */
if (targetCount == 0) {
return fromIndex;
}
int strLastIndex = targetOffset + targetCount - 1;
char strLastChar = target[strLastIndex];
int min = sourceOffset + targetCount - 1;
int i = min + fromIndex;
startSearchForLastChar:
while (true) {
while (i >= min && source[i] != strLastChar) {
i--;
}
if (i < min) {
return -1;
}
int j = i - 1;
int start = j - (targetCount - 1);
int k = strLastIndex - 1;
while (j > start) {
if (source[j--] != target[k--]) {
i--;
continue startSearchForLastChar;
}
}
return start - sourceOffset + 1;
}
}
4.public char charAt(int index),返回指定索引处的 char
值。索引范围为从 0
到 length() - 1
String s = new String("abcde");
char charAt = s.charAt(3);
System.out.println(charAt);//d
源码:
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) { //防止下标越界
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
5.public boolean contains(String str),当且仅当此字符串包含指定的 str字符串序列时,返回 true。
String s = new String("abcde");
boolean contains = s.contains("a");
System.out.println(contains); //true
源码:
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
6.public boolean isEmpty(),当且仅当 length()
为 0 时返回 true。
String s = "sasd";
String s1 = "";
String s2 = null; //报错
System.out.println(s.isEmpty());//false
System.out.println(s1.isEmpty());//true
System.out.println(s2.isEmpty());//NullPointerException
源码:
public boolean isEmpty() {
return value.length == 0;
}
注意:只有双引号才算空,有空格也不算空,另外,当为null的时候会报错。
7.public boolean startsWith(String str) 测试此字符串是否以指定的前缀开始。 public boolean endsWith(String str) 测试此字符串是否以指定的后缀结束。
String a = "abcdef123ghabcdef";
System.out.println(a.startsWith("a")); //true
System.out.println(a.startsWith("abc"));//true
System.out.println(a.startsWith("abd"));//false
System.out.println(a.endsWith("f")); //true
System.out.println(a.endsWith("ef")); //true
System.out.println(a.endsWith("abc"));//false
源码:
prefix:判断是不是以这个字符串开头或结尾
toffset:从字符串(字符数组)的哪个下标开始,不写默认为0
public boolean startsWith(String prefix) {
return startsWith(prefix, 0);
}
public boolean startsWith(String prefix, int toffset) {
char ta[] = value; //调用这个方法的那个字符串(数组)用char ta[]接收
int to = toffset;
char pa[] = prefix.value;//把传进来的形参转换为char数组,并用char pa[]接收
int po = 0;
int pc = prefix.value.length;
// Note: toffset might be near -1>>>1.//注意:开始比较的那个位置不能小于0
if ((toffset < 0) || (toffset > value.length - pc)) {
return false;
}
while (--pc >= 0) { //控制的是形参字符串(上面转换为char数组了)的长度
if (ta[to++] != pa[po++]) { //挨个判断,有一个不等就返回false
return false;
}
}
return true;
}
//endsWith()底层也是调用startsWith()方法,只是传进去的参数做了改变。
public boolean endsWith(String suffix) {
return startsWith(suffix, value.length - suffix.value.length);
}
// value.length - suffix.value.length
// 用源字符串(数组)长度 减去 要比较字符串(数组)的长度,结果即为最后的位置,正好比较完
8. public boolean equals(String str),判断字符串的内容是否相等 public boolean equalsIgnoreCase(String str);判断字符串的内容是否相等不区分大小写。
当字符串和常量进行比较
错误写法:str.equals("张三");
正确写法:"张三".equals(str);
源码:(String类中重写了.equals方法,所以判断的是内容)
public boolean equals(Object anObject) {
if (this == anObject) { //"=="判断内存地址
return true;
}
if (anObject instanceof String) { //向下转型
String anotherString = (String)anObject;//强转
int n = value.length;
if (n == anotherString.value.length) { //判断长度,若不等直接返回false
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;
}
源码:
public boolean equalsIgnoreCase(String anotherString) {
return (this == anotherString) ? true
: (anotherString != null)
&& (anotherString.value.length == value.length)
&& regionMatches(true, 0, anotherString, 0, value.length);
}
//这里运用了三目运算符,如果两个数组内存地址相等,直接返回true,
//否则,要满足一下三点才返回true,否则返会false
// 1.传进来的数组不为空
// 2.两个数组的长度相同
// 3.调用regionMatches()方法且返回的是true
regionMatches()方法源码:
各形参所代表的含义:
ignoreCase:如果是true。在比较的时候忽略大小写,
toffset:源字符串(构造方法转换为char数组了)开始比较的下标
other:要被比较的字符串(char数组)
ooffset:要被比较的字符串(char数组)开始比较的下标
len:要被比较的字符数
public boolean regionMatches(boolean ignoreCase, int toffset,
String other, int ooffset, int len) {
char ta[] = value; //用char ta[]接收源字符串
int to = toffset;
char pa[] = other.value; //Srting类型字符串+.value转换为字符数组
int po = ooffset;
// Note: toffset, ooffset, or len might be near -1>>>1.
// 注意:toffset, ooffset, or len这三个值不能小于0 (大概意思)
/*
*两个比较的字符串(char数组)开始比较的位置有一个下标小于0
*或者要比较的长度超过本来数组的长度,即越界,只要有一个成立就返回false
* toffset > (long)value.length - len)可以理解为:
* (toffset + len) > value.length 即开始比较的下标+要比较长度>数组长度
*/
if ((ooffset < 0) || (toffset < 0)
|| (toffset > (long)value.length - len)
|| (ooffset > (long)other.value.length - len)) {
return false;
}
while (len-- > 0) {
char c1 = ta[to++];
char c2 = pa[po++]; //把两个字符串(char数组)中的内容挨个赋值给c1,c2
if (c1 == c2) { //然后拿c1,c2挨个比较
continue; //如果相等,就结束本次循环,继续下一次,否则往下找执行条件
}
if (ignoreCase) { //传进来的boolen类型的形参,为true时才执行这段
// If characters don't match but case may be ignored,
// 如果字符不匹配,大小写可能被忽略,
// try converting both characters to uppercase.
// 试着把两个字符都转换成大写。
// If the results match, then the comparison scan should
// 如果结果匹配,则比较扫描应该
// continue.
//char toUpperCase(char ch) 形参cf为要转换的字母
//返回转换后字符的大写形式,如果有的话;否则返回字符本身。
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) {
continue;
}
// Unfortunately, conversion to uppercase does not work properly
// 不幸的是,转换成大写不能正常工作
// for the Georgian alphabet, which has strange rules about case
// 因为Georgian alphabet有奇怪的大小写规则转换。
// conversion. So we need to make one last check before
// 所以我们需要做最后一次检查
// exiting.
if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
continue;
}
}
return false;
}
return true;
}
因为()里面的通常是形参,当传来的为null的时候,会出现异常,
还有不要直接出现这种字符串,要用变量去接收,或者定义为常量。
9. public String replace(String oldStr,String newStr);将字符串中的oldStr替换成newStr,然后得到一个新字符串
String a = "abcdeabcf42abc";
System.out.println(a.replace("abc", "XXX"));//XXXdeXXXf42XXX
源码:把数组中的oldChar字符换成newChar字符
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) { //如果两个字符相同,那么就返回源字符串,不重新new
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */ //避免失败的操作?
while (++i < len) {
if (val[i] == oldChar) { //找到这个字符的位置
break;
}
}
if (i < len) {
char buf[] = new char[len]; //创建一个新数组,记录更改之后的
for (int j = 0; j < i; j++) { //把要替换位置之前的字符重新复制到一个新数组中
buf[j] = val[j];
}
while (i < len) { //从要替换的这个位置,循环到最后,把内容挨个复制到新数组中
char c = val[i]; //
buf[i] = (c == oldChar) ? newChar : c; //三目判断是更换还是复制原来的
i++;
}
return new String(buf, true);
}
}
return this;
}
当要更换的是字符串的时候,调用的是以下方法:CharSequence字符序列,但该就是字符串了吧...
public String replace(CharSequence target, CharSequence replacement) {
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
原谅我没有看懂这个玩意.....
10.public String substring(int beginIndex, int endIndex),将字符串中第beginIndex(包含)到endIndex(不包含)截取 public String substring(int beginIndex), 将字符串中第beginIndex(包含)到最后截取
String a = "abcdeabcf42abc";
System.out.println(a.substring(5, 10));//abcf4
System.out.println(a.substring(5));//abcf42abc
为什么不包含endIndex?
当不写的时候,默认截取到数组的最后,而数组是从0开始计起,
所以截取到最后即为lengt-1个数,所以输入10即截取到10-1=9个。
多想想吧
源码:
public String substring(int beginIndex) {
if (beginIndex < 0) { //开始位置小于0,抛出异常
throw new StringIndexOutOfBoundsException(beginIndex);
}
int subLen = value.length - beginIndex;//被截取后新数组的长度
if (subLen < 0) { //被截取后新的数组长度小于0就抛出异常
throw new StringIndexOutOfBoundsException(subLen);
}
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}
/*
*如果截取的开始位置为0,那么直接返回这个字符串(没有new一个)
*否则,便会调用String的带三个参数的构造方法,从新new一个String保存并返回该结果
*/
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) { //截取的位置的下标大于源字符串(数组),抛出异常
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
//返回该数组的条件多了一个,即截取的是最后一个位置,即endIndex == value.length
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}
11.public String trim(),去除前面和尾部的空格,(中间的空格去除不了哦)
String password="123456 ";//多了个空格
System.out.println("123456".equals(password));//false
String b=password.trim();
System.out.println("123456".equals(b));//true
源码:
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
12. public String concat(String str),将指定字符串连接到此字符串的结尾
String a = "abcdeabcf42abc";
System.out.println(a.concat("555").equals(a));//false
System.out.println(a.concat("").equals(a));//true
如果参数字符串的长度为 0,则返回此 String 对象。
源码:
public String concat(String str) {
int otherLen = str.length(); //记录指定字符串的长度
if (otherLen == 0) {
return this;
}
int len = value.length;
//将原数组复制,并把长度增加指定字符串的长度
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len); //把str添加到buf数组len位置之后
return new String(buf, true); //返回一个新字符串
}
13.public String[] split(String str),拆分(删除)数组中的str字符串,返回的是String数组
String a="123dabd456dccc";
String[] bs=a.split("d");
//split可以根据正则表达式切割
for (int i = 0; i < bs.length; i++) {
System.out.println(bs[i]);
}
源码:
public String[] split(String regex) {
return split(regex, 0);
}
public String[] split(String regex, int limit) {
/* fastpath if the regex is a
(1)one-char String and this character is not one of the
RegEx's meta characters ".$|()[{^?*+\\", or
(2)two-char String and the first char is the backslash and
the second is not the ascii digit or ascii letter.
*/
char ch = 0;
if (((regex.value.length == 1 &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
(regex.length() == 2 &&
regex.charAt(0) == '\\' &&
(((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
((ch-'a')|('z'-ch)) < 0 &&
((ch-'A')|('Z'-ch)) < 0)) &&
(ch < Character.MIN_HIGH_SURROGATE ||
ch > Character.MAX_LOW_SURROGATE))
{
int off = 0;
int next = 0;
boolean limited = limit > 0;
ArrayList<String> list = new ArrayList<>();
while ((next = indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(substring(off, next));
off = next + 1;
} else { // last one
//assert (list.size() == limit - 1);
list.add(substring(off, value.length));
off = value.length;
break;
}
}
// If no match was found, return this
if (off == 0)
return new String[]{this};
// Add remaining segment
if (!limited || list.size() < limit)
list.add(substring(off, value.length));
// Construct result
int resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
resultSize--;
}
}
String[] result = new String[resultSize];
return list.subList(0, resultSize).toArray(result);
}
return Pattern.compile(regex).split(this, limit);
}
14.public char[] toCharArray(),将此字符串转换为一个新的字符数组。
String a="abc";
char[] bs=a.toCharArray();
for (int i = 0; i < bs.length; i++) {
System.out.println(bs[i]);
}
源码:
不能使用数组复制,因为类初始化顺序问题
public char[] toCharArray() {
// Cannot use Arrays.copyOf because of class initialization order issues
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}
内容有点长,我也觉得很啰嗦了,怕是很难有兴趣看完,不过这玩意就是这样的....
以上纯属个人理解观点(可能会有理解错的,希望不会把你带往错误的道路),欢迎留言一起讨论!