更多关于string
String类字符串比较大概有4种方法:Compare(),CompareTo(), CompareOrdinal()和Equals().
1、Compare()方法是CompareTo()的静态版本.
2、CompareOrdinal()对两个字符串进行比较,不考虑本地化语言和文化.(所以运行速度比<1>快很多)
3、而Equals()与"=="是等价的,只要使用"=="运算符,就会调用Equals()方法.
1 //静态Equals 2 start = Environment.TickCount; 3 for (int i = 0; i < Num; i++) 4 { 5 string.Equals(s1, s2); 6 } 7 end = Environment.TickCount; 8 Console.WriteLine("静态Equals : " + (end - start)); 9 10 //实例Equals 11 start = Environment.TickCount; 12 for (int i = 0; i < Num; i++) 13 { 14 s1.Equals(s2); 15 } 16 end = Environment.TickCount; 17 Console.WriteLine("实例Equals : " + (end - start));
静态的Equals:
public static bool Equals(string a, string b) { return ((a == b) || (((a != null) && (b != null)) && EqualsHelper(a, b))); }
实例的Equals:
public bool Equals(string value) { if (this == null) { throw new NullReferenceException(); } if (value == null) { return false; } return (object.ReferenceEquals(this, value) || EqualsHelper(this, value)); }
EqualsHelper:
private static unsafe bool EqualsHelper(string strA, string strB) { int length = strA.Length; if (length != strB.Length) { return false; } fixed (char* chRef = &strA.m_firstChar) { fixed (char* chRef2 = &strB.m_firstChar) { char* chPtr = chRef; char* chPtr2 = chRef2; while (length >= 10) { if ((((*(((int*) chPtr)) != *(((int*) chPtr2))) || (*(((int*) (chPtr + 2))) != *(((int*) (chPtr2 + 2))))) || ((*(((int*) (chPtr + 4))) != *(((int*) (chPtr2 + 4)))) || (*(((int*) (chPtr + 6))) != *(((int*) (chPtr2 + 6)))))) || (*(((int*) (chPtr + 8))) != *(((int*) (chPtr2 + 8))))) { break; } chPtr += 10; chPtr2 += 10; length -= 10; } while (length > 0) { if (*(((int*) chPtr)) != *(((int*) chPtr2))) { break; } chPtr += 2; chPtr2 += 2; length -= 2; } return (length <= 0); } } }
【Equals()与"=="是是否真的是等价的?】: 《下面内容转载地址:http://blog.sina.com.cn/s/blog_6a10187d0101c4mj.html》
比较一般分为两种,“==”操作符和equals()方法。
- String是一个对象,对象进行“==”比较时,比较是内存地址。
- String对象的equals和compareTo等方法都被重写为比较内容。做内容比较时用这些方法,而不用“操作符”。
- 整个Java的范畴来说,对象之间比较一般都不用操作符,而用自身提供的方法,只有基础类型int char之间用操作符比较。
字符串赋值得注意得是:
- 创建String类型的变量有两种方法
String st = "相等"
String st = new String("相等");
第一种方式,会把"相等"这个字符串放在字符缓冲区中,如果再出现一个String sr = "相等",就直接把缓冲区中的地址赋给sr,就会出现 st 与 sr 指向的内存地址相同的。
用第二种方式,就会各自开辟一个内存地址,新建两个对象,"相等"有一个地址,st也有另一个地址,二者的内容一样。 - 如果是字符串直接赋值,还要注意一点的是,如String s3 = "ab";编译器会先检查字符串常量缓冲区是否已存在"ab",如果已存在,直接将"ab"的地址赋给s3;如果不存在,则先创建对象"ab",再将"ab"的地址赋给s3。
- 如果有String s2 = s1+"b";相当于是s1+"b"重新生成一个new String()对象,这个地址和字符串的地址也是不一样的。
代码说明:
String s1 = "a";
String s2 = s1+"b";
String s3 = "ab";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
System.out.println(s2.equals("ab"));
System.out.println(s3.equals("ab"));
System.out.println(s3.equals(s2));
System.out.println(s3 == s2);
输出结果为:
false
true
true
true
true
false