关于字符串的处理过程 System.out.println("a".toLowerCase() + "b" == "ab"); // false请问各朋友,上面的"a".toLowerCase() + "b"的处理过程是怎么样的? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 先把"a"进行小写处理,然后和"b"连接在一起组成"ab"有啥看不懂的,典型的从左向右处理 "a".toLowerCase() + "b" 这个块使用的内存位置在 对空间中"ab" 这块是在栈空间中 ==比较的是两个对象的内存地址是否一致所以结果为false System.out.println(("a".toLowerCase() + "b").equals("ab")); LZ问的是toLowerCase的过程,看了下源码,没耐心看下去,给你贴一下,自己看吧 public String toLowerCase(Locale locale) { if (locale == null) { throw new NullPointerException(); } int firstUpper; /* Now check if there are any characters that need to be changed. */ scan: { for (firstUpper = 0 ; firstUpper < count; ) { char c = value[offset+firstUpper]; if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) { int supplChar = codePointAt(firstUpper); if (supplChar != Character.toLowerCase(supplChar)) { break scan; } firstUpper += Character.charCount(supplChar); } else { if (c != Character.toLowerCase(c)) { break scan; } firstUpper++; } } return this; } char[] result = new char[count]; int resultOffset = 0; /* result may grow, so i+resultOffset * is the write location in result */ /* Just copy the first few lowerCase characters. */ System.arraycopy(value, offset, result, 0, firstUpper); String lang = locale.getLanguage(); boolean localeDependent = (lang == "tr" || lang == "az" || lang == "lt"); char[] lowerCharArray; int lowerChar; int srcChar; int srcCount; for (int i = firstUpper; i < count; i += srcCount) { srcChar = (int)value[offset+i]; if ((char)srcChar >= Character.MIN_HIGH_SURROGATE && (char)srcChar <= Character.MAX_HIGH_SURROGATE) { srcChar = codePointAt(i); srcCount = Character.charCount(srcChar); } else { srcCount = 1; } if (localeDependent || srcChar == '\u03A3') { // GREEK CAPITAL LETTER SIGMA lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale); } else { lowerChar = Character.toLowerCase(srcChar); } if ((lowerChar == Character.ERROR) || (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) { if (lowerChar == Character.ERROR) { lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale); } else if (srcCount == 2) { resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount; continue; } else { lowerCharArray = Character.toChars(lowerChar); } /* Grow result if needed */ int mapLen = lowerCharArray.length; if (mapLen > srcCount) { char[] result2 = new char[result.length + mapLen - srcCount]; System.arraycopy(result, 0, result2, 0, i + resultOffset); result = result2; } for (int x=0; x<mapLen; ++x) { result[i+resultOffset+x] = lowerCharArray[x]; } resultOffset += (mapLen - srcCount); } else { result[i+resultOffset] = (char)lowerChar; } } return new String(0, count+resultOffset, result); } //反编译:System.out.println((new StringBuilder()).append("a".toLowerCase()).append("b").toString() == "ab");字节码: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: new #3; //class java/lang/StringBuilder 6: dup 7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V 10: ldc #5; //String a 12: invokevirtual #6; //Method java/lang/String.toLowerCase:()Ljava/lang/String; 15: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 18: ldc #8; //String b 20: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 23: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 26: ldc #10; //String ab 28: if_acmpne 35 31: iconst_1 32: goto 36 35: iconst_0 36: invokevirtual #11; //Method java/io/PrintStream.println:(Z)V 39: return System.out.println("a".toLowerCase() + "b" == "ab"); // falseSystem.out.println("ab".toLowerCase() == "ab"); // trueSystem.out.println("AB".toLowerCase() == "ab"); // false为什么结果会这样? 2楼的朋友说得好像有点道理, 不过还是不明白, 不知哪位能否清楚的介绍下? PS: 这是一道IBM的笔试题, 1楼的朋友不要小看了...... 看了一下4楼贴出的源代码scan: { for (firstUpper = 0 ; firstUpper < count; ) { char c = value[offset+firstUpper]; if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) { int supplChar = codePointAt(firstUpper); if (supplChar != Character.toLowerCase(supplChar)) { break scan; } firstUpper += Character.charCount(supplChar); } else { if (c != Character.toLowerCase(c)) { break scan; } firstUpper++; } } return this; }这一段是判断字符串是否需要转换,如果不需要的话就返回自身。因此这一句System.out.println("ab".toLowerCase() == "ab"); // true相当于System.out.println("ab" == "ab"); 在方法的最后一部分里面有这么一段 return new String(0, count+resultOffset, result);即最后如果字符串里面有字符都转换为小写,则返回一个新的字符串,这个字符串是new出来的,放在堆内存里面后面用着个字符串来进行连接时,新生成的字符串也是放在堆内存里边的System.out.println("a".toLowerCase() + "b" == "ab"); // falseSystem.out.println("AB".toLowerCase() == "ab"); // false这时候你拿堆内存的字符串和常量池的字符串比较结果当然是false 楼上的大侠讲的似乎有些道理,可我的问题是"a".toLowerCase()不也是没有转换小写吗。。应该是返回本身啊难道你是说当a+b变成"ab"的时候,实际上对内存里new了一个String对象? 没错,再看:[code]System.out.println("a" + "b" == "ab"); // true[code] 字符串最最让人迷惑的问题,如:String str="a"+"b"+"c";问创建了几个对象?以及楼上各位所说的问题,能不能有谁能够把这些说明白点 String str="a"+"b"+"c";问创建了几个对象?这个问题真的很无聊...如果想让两个字符串的地址相等就用String 类的 intern() 方法,返回一个字符串,内容与此字符串相同,但一定取自具有唯一字符串的池。 按照10楼java1109兄的说法,连接字符串操作是新建了一个字符串了。验证中…… 反正比对象地址用==,比值就用equals就对了... "ab" 应该是在Data Segment吧? 这时候,"a".toLowerCase() 和 "a" 比较是用“==”,而不是equals()方法,故比较的是地址,就是比较new出来的,就像 String s1 = new String("china"); String s2 = new String("china"); System.out.println(s1 == s2); 的时候,结果是false 而 equals()方法是String类从其父类Object类中继承并重写了,这可以查API文档,equals方法比较的是字符串的序列,可明白? //太好玩了,呵呵System.out.println("a".toLowerCase() + "b" == "ab"); // falseSystem.out.println("ab".toLowerCase() == "ab"); // trueSystem.out.println("AB".toLowerCase() == "ab"); // falseSystem.out.println("ab".concat("") == "ab"); // trueSystem.out.println("ab".substring(0) == "ab"); // trueSystem.out.println("ab".toString() == "ab"); // trueSystem.out.println("ab".trim() == "ab"); // true Socket的accept()问题。没客户端也运行! 刚学JAVA 写的一个记事本程序 出问题了!! 这个程序为什么返回FAISE啊?? 求助:类的问题,计算成绩! ResultSet转换成String[][] 50分!!!! 刷新applet弹出来的进度条 请教关于JAVA 的UI设计! 有没有跟JBuilder一样支持便捷EJB开发的开发工具吗?而且要内存占用小 jdk documentation 编程小白,求大佬帮忙看看 java 采集网页信息 继承问题
"ab" 这块是在栈空间中
==比较的是两个对象的内存地址是否一致
所以结果为false
public String toLowerCase(Locale locale) {
if (locale == null) {
throw new NullPointerException();
} int firstUpper; /* Now check if there are any characters that need to be changed. */
scan: {
for (firstUpper = 0 ; firstUpper < count; ) {
char c = value[offset+firstUpper];
if ((c >= Character.MIN_HIGH_SURROGATE) &&
(c <= Character.MAX_HIGH_SURROGATE)) {
int supplChar = codePointAt(firstUpper);
if (supplChar != Character.toLowerCase(supplChar)) {
break scan;
}
firstUpper += Character.charCount(supplChar);
} else {
if (c != Character.toLowerCase(c)) {
break scan;
}
firstUpper++;
}
}
return this;
} char[] result = new char[count];
int resultOffset = 0; /* result may grow, so i+resultOffset
* is the write location in result */ /* Just copy the first few lowerCase characters. */
System.arraycopy(value, offset, result, 0, firstUpper); String lang = locale.getLanguage();
boolean localeDependent =
(lang == "tr" || lang == "az" || lang == "lt");
char[] lowerCharArray;
int lowerChar;
int srcChar;
int srcCount;
for (int i = firstUpper; i < count; i += srcCount) {
srcChar = (int)value[offset+i];
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE &&
(char)srcChar <= Character.MAX_HIGH_SURROGATE) {
srcChar = codePointAt(i);
srcCount = Character.charCount(srcChar);
} else {
srcCount = 1;
}
if (localeDependent || srcChar == '\u03A3') { // GREEK CAPITAL LETTER SIGMA
lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
} else {
lowerChar = Character.toLowerCase(srcChar);
}
if ((lowerChar == Character.ERROR) ||
(lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
if (lowerChar == Character.ERROR) {
lowerCharArray =
ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
} else if (srcCount == 2) {
resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
continue;
} else {
lowerCharArray = Character.toChars(lowerChar);
} /* Grow result if needed */
int mapLen = lowerCharArray.length;
if (mapLen > srcCount) {
char[] result2 = new char[result.length + mapLen - srcCount];
System.arraycopy(result, 0, result2, 0,
i + resultOffset);
result = result2;
}
for (int x=0; x<mapLen; ++x) {
result[i+resultOffset+x] = lowerCharArray[x];
}
resultOffset += (mapLen - srcCount);
} else {
result[i+resultOffset] = (char)lowerChar;
}
}
return new String(0, count+resultOffset, result);
}
//反编译:
System.out.println((new StringBuilder()).append("a".toLowerCase()).append("b").toString() == "ab");字节码:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3; //class java/lang/StringBuilder
6: dup
7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
10: ldc #5; //String a
12: invokevirtual #6; //Method java/lang/String.toLowerCase:()Ljava/lang/String;
15: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
18: ldc #8; //String b
20: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
26: ldc #10; //String ab
28: if_acmpne 35
31: iconst_1
32: goto 36
35: iconst_0
36: invokevirtual #11; //Method java/io/PrintStream.println:(Z)V
39: return
System.out.println("a".toLowerCase() + "b" == "ab"); // false
System.out.println("ab".toLowerCase() == "ab"); // true
System.out.println("AB".toLowerCase() == "ab"); // false为什么结果会这样? 2楼的朋友说得好像有点道理, 不过还是不明白, 不知哪位能否清楚的介绍下?
for (firstUpper = 0 ; firstUpper < count; ) {
char c = value[offset+firstUpper];
if ((c >= Character.MIN_HIGH_SURROGATE) &&
(c <= Character.MAX_HIGH_SURROGATE)) {
int supplChar = codePointAt(firstUpper);
if (supplChar != Character.toLowerCase(supplChar)) {
break scan;
}
firstUpper += Character.charCount(supplChar);
} else {
if (c != Character.toLowerCase(c)) {
break scan;
}
firstUpper++;
}
}
return this;
}这一段是判断字符串是否需要转换,
如果不需要的话就返回自身。
因此这一句
System.out.println("ab".toLowerCase() == "ab"); // true
相当于System.out.println("ab" == "ab"); 在方法的最后一部分里面有这么一段 return new String(0, count+resultOffset, result);即最后如果字符串里面有字符都转换为小写,则返回一个新的字符串,
这个字符串是new出来的,放在堆内存里面
后面用着个字符串来进行连接时,新生成的字符串也是放在堆内存里边的
System.out.println("a".toLowerCase() + "b" == "ab"); // false
System.out.println("AB".toLowerCase() == "ab"); // false
这时候你拿堆内存的字符串和常量池的字符串比较结果当然是false
楼上的大侠讲的似乎有些道理,可我的问题是"a".toLowerCase()不也是没有转换小写吗。。应该是返回本身啊难道你是说当a+b变成"ab"的时候,实际上对内存里new了一个String对象?
[code]
System.out.println("a" + "b" == "ab"); // true
[code]
以及楼上各位所说的问题,能不能有谁能够把这些说明白点
如果想让两个字符串的地址相等就用String 类的 intern() 方法,返回一个字符串,内容与此字符串相同,但一定取自具有唯一字符串的池。
"ab" 应该是在Data Segment吧?
这时候,"a".toLowerCase() 和 "a" 比较是用“==”,而不是equals()方法,故比较的是地址,就是比较new出来的,就像 String s1 = new String("china");
String s2 = new String("china");
System.out.println(s1 == s2); 的时候,结果是false
而 equals()方法是String类从其父类Object类中继承并重写了,这可以查API文档,equals方法比较的是字符串的序列,可明白?
//太好玩了,呵呵
System.out.println("a".toLowerCase() + "b" == "ab"); // false
System.out.println("ab".toLowerCase() == "ab"); // true
System.out.println("AB".toLowerCase() == "ab"); // false
System.out.println("ab".concat("") == "ab"); // true
System.out.println("ab".substring(0) == "ab"); // true
System.out.println("ab".toString() == "ab"); // true
System.out.println("ab".trim() == "ab"); // true