题目:写一个字符串反转函数,输入 abcdef 转换成 edcba
没写什么特别有意义的东西,就随便做做笔记。
//反转函数
public static String reverse(String str){
char[] c1 = str.toCharArray();
char[] c2 = new char[c1.length];
for(int i=0,j=c1.length-1;i<c1.length;i++,j--){
c2[j]=c1[i];
}
return c2.toString();
}
//main 函数
public static void main(String args[]){
String str = "abcdedf";
System.out.println(str);
str = reverse(str);
System.out.println(str);
}
运行,发现输出的不对:
abcdedf
[C@4517d9a3
查看 c2.toString( )一看,发现调用的是 Object 类的 toString( )方法。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
修改反转函数:
//反转函数
public static String reverse(String str){
char[] c1 = str.toCharArray();
char[] c2 = new char[c1.length];
for(int i=0,j=c1.length-1;i<c1.length;i++,j--){
c2[j]=c1[i];
}
return new String(c2);
}
运行,输出:
abcdedf
fdedcba
然后想去看看自己写的反转函数和 String 自带的反转函数的区别在哪,才发现,原来 String 没有反转函数。
然后发现 StringBuffer 和 StringBuilder 才有 reverse 函数,且该这两个类中的 reverse 函数实际上调用的是父类 AbstractStringBuilder 的 reverse 函数。
题外话:StringBuffer 和 StringBuilder 中的绝大多数方法都是去调用父类的相应方法,而 StringBuffer 较 StringBuilder 而言,区别是 StringBuffer 是线程安全的,因为 StringBuffer 的绝大多数方法都会使用 synchronized 进行修饰,以此保证线程安全。
这是AbstractStringBuilder 的 reverse 函数:
public AbstractStringBuilder reverse() {
boolean hasSurrogates = false;
int n = count - 1;
// 折半交换
for (int j = (n-1) >> 1; j >= 0; j--) {
int k = n - j; //k+j=n
char cj = value[j];
char ck = value[k];
value[j] = ck;
value[k] = cj;
if (Character.isSurrogate(cj) ||
Character.isSurrogate(ck)) {
hasSurrogates = true;
}
}
if (hasSurrogates) {
reverseAllValidSurrogatePairs();
}
return this;
}
那两个 if 判断是在干什么,我没看懂。但看懂了它的核心思想是折半交换,算是新的思路吧。其实我感觉把 cj 和 ck 的定义放在 for 外面会更节省空间,不知道说的对不对。
突然好疑惑,上面 c2.toString( ) 方法调用的是 Object 类的 toString( ) 方法。我知道 c2 是字符数组,但是该对象所属的类是哪个类?数组类?
搞懂了再补充上来。