Java 字符串之间是如何比较的?
比较两个字符串时,实际发生了什么?我们如何确定字符串a中的内容等于字符串B?我们是否在unicode字符表中查找两个字符串的元素到元素的比较?如果是,那么equals()如何知道像“ABC”这样的字符串中的元素,equals()如何从BC中提取一个元素来与其他字符串的第一个元素进行比较?如果有疑问,请始终检查: 将此字符串与指定的对象进行比较。如果 并且仅当参数不为null并且是 表示与此对象相同的字符序列 在字符串中使用equals时,实际上会发生这种情况Java 字符串之间是如何比较的?,java,string,comparison,Java,String,Comparison,比较两个字符串时,实际发生了什么?我们如何确定字符串a中的内容等于字符串B?我们是否在unicode字符表中查找两个字符串的元素到元素的比较?如果是,那么equals()如何知道像“ABC”这样的字符串中的元素,equals()如何从BC中提取一个元素来与其他字符串的第一个元素进行比较?如果有疑问,请始终检查: 将此字符串与指定的对象进行比较。如果 并且仅当参数不为null并且是 表示与此对象相同的字符序列 在字符串中使用equals时,实际上会发生这种情况 public boolean equ
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) {
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;
}
因此,只有当您正在比较其他字符串时,如果您有相同的序列,它才会返回,因为它正在比较字符。如果有疑问,请始终检查: 将此字符串与指定的对象进行比较。如果 并且仅当参数不为null并且是 表示与此对象相同的字符序列 在字符串中使用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) {
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;
}
因此,只有当您比较其他字符串时,如果您有相同的序列,它才会返回,因为它是比较字符。字符串基本上是围绕
char[]
的不可变包装,有许多有用的实用方法
因此,要检查两个字符串是否相等,只需检查它们是否都具有大小相同且内容相同的char
数组
使用具有处理数组的有用方法的类,简化的String
实现可能如下所示:
public final class String {
private char[] value;
public String(char[] value) {
this.value = value.clone();
}
@Override
public boolean equals(Object obj) {
if (! (obj instanceof String))
return false;
String other = (String) obj;
return Arrays.equals(this.value, other.value);
}
@Override
public int hashCode() {
return Arrays.hashCode(this.value);
}
public char[] toCharArray() {
return this.value.clone();
}
public String substring(int beginIndex, int endIndex) {
return new String(Arrays.copyOfRange(this.value, beginIndex, endIndex));
}
// more utility methods
}
真正的String
类更加复杂,具体方式取决于Java版本
例如,在早期版本中,char[]
可以由多个String
对象共享,因此例如substring()
不需要复制数组
在以后的版本中,为了节省空间,优化已更改为尽可能将字符存储在byte
()数组中,而不是char
()数组中
这些不同的优化当然会使
String
实用程序方法的内部代码复杂化,这可能会让您在查看JDK源代码时感到困惑。字符串基本上是围绕char[]
的不可变包装,有许多有用的实用程序方法
因此,要检查两个字符串是否相等,只需检查它们是否都具有大小相同且内容相同的char
数组
使用具有处理数组的有用方法的类,简化的String
实现可能如下所示:
public final class String {
private char[] value;
public String(char[] value) {
this.value = value.clone();
}
@Override
public boolean equals(Object obj) {
if (! (obj instanceof String))
return false;
String other = (String) obj;
return Arrays.equals(this.value, other.value);
}
@Override
public int hashCode() {
return Arrays.hashCode(this.value);
}
public char[] toCharArray() {
return this.value.clone();
}
public String substring(int beginIndex, int endIndex) {
return new String(Arrays.copyOfRange(this.value, beginIndex, endIndex));
}
// more utility methods
}
真正的String
类更加复杂,具体方式取决于Java版本
例如,在早期版本中,char[]
可以由多个String
对象共享,因此例如substring()
不需要复制数组
在以后的版本中,为了节省空间,优化已更改为尽可能将字符存储在byte
()数组中,而不是char
()数组中
这些不同的优化当然会使
String
实用程序方法的内部代码复杂化,这可能会使您在查看JDK源代码时感到困惑。编译器不知道。String类的equals()方法在运行时执行此操作。不是编译器。编译器将源代码转换为字节码。它不执行代码。@jbnize不好,但它是如何执行的?我看了equals(),实际上我不理解它。好吧,发布你看的代码(它根据Java版本而变化),告诉我们你在代码中不理解的地方。但基本上,它会比较两个字符串的长度,然后逐个比较字符。仅供参考,链接到OpenJDK for Java 10。编译器不知道。String类的equals()方法在运行时执行此操作。不是编译器。编译器将源代码转换为字节码。它不执行代码。@jbnize不好,但它是如何执行的?我看了equals(),实际上我不理解它。好吧,发布你看的代码(它根据Java版本而变化),告诉我们你在代码中不理解的地方。但基本上,它会比较两个字符串的长度,然后逐个比较字符。仅供参考,OpenJDK for Java 10中的链接。有点不相关的注意:共享单个字符[]实际上是过早的优化。他们认为可以优化一些字符串操作以共享同一数组并指定起点和终点,这样String.substring就不会创建一个全新的字符串,但他们没有考虑web开发人员将下载整个网页并拆分/过滤掉几个单词的想法,希望收集原始字符串。删除共享的备份阵列更多的是一种去优化:)有些不相关的注意:共享单个char[]实际上是一种过早的优化。他们认为可以优化一些字符串操作以共享同一数组并指定起点和终点,这样String.substring就不会创建一个全新的字符串,但他们没有考虑web开发人员将下载整个网页并拆分/过滤掉几个单词的想法,希望收集原始字符串。删除共享备份阵列更像是一种去优化:)