子字符串方法 - 相等性测试失败
Substring method - Equality test fails
This question之前有人问过,但没有真正回答。
如果 substring 方法创建了一个新对象,而这个对象在池中 "interned",那么为什么 ==
return 为 false。这是我的代码:
public class StringTest {
public static void main(String[] args) {
String str1 = "The dog was happy";
String str2 = "The hog was happy";
System.out.println(str1.substring(5));// just to make sure
System.out.println(str2.substring(5));
if (str1.substring(5) == str2.substring(5)) {
System.out.println("Equal using equality operator");
} else {
System.out.println("Not equal using equality operator");
}
if (str1.substring(5).equals(str2.substring(5))) {
System.out.println("Equal using equals method");
} else {
System.out.println("Not equal using equals method");
}
}
}
输出为:1. og 很高兴 2. og 很高兴 3. 使用相等运算符不等于 4. 使用 equals 方法等于
P.S。这是子字符串方法源代码:
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);
}
P.S。这个问题已被标记为已被多人提问和回答,但我在 Stack Overflow 上找不到一个实例,其中有人真正解释了为什么 substring(0) 的计算结果为真。
答案就在你的问题本身。
尝试执行以下操作:
String str1 = "The dog was happy";
String str2 = "The dog was happy";
if (str1 == str2)
{
System.out.println("Equal using equality operator");
}
else
{
System.out.println("Not equal using equality operator");
}
你会得到"Equal using equality operator"。原因是您已将 str1 和 str2 都声明为字符串文字,并且内部池的概念适用。
现在,当您根据字符串 class 定义执行 str1.substring(5) 时,它 returns 是一个对象,而不是文字。因此 == 给出了错误的结果。
字符串class子串方法:
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
如果您希望 == 对子字符串起作用,请对您的子字符串使用 intern() 方法。
变化:
if (str1.substring(5) == str2.substring(5))
到
if (str1.substring(5).intern() == str2.substring(5).intern())
一个很好的文档来理解字符串创建和池化的细节:https://www.journaldev.com/797/what-is-java-string-pool
This question之前有人问过,但没有真正回答。
如果 substring 方法创建了一个新对象,而这个对象在池中 "interned",那么为什么 ==
return 为 false。这是我的代码:
public class StringTest {
public static void main(String[] args) {
String str1 = "The dog was happy";
String str2 = "The hog was happy";
System.out.println(str1.substring(5));// just to make sure
System.out.println(str2.substring(5));
if (str1.substring(5) == str2.substring(5)) {
System.out.println("Equal using equality operator");
} else {
System.out.println("Not equal using equality operator");
}
if (str1.substring(5).equals(str2.substring(5))) {
System.out.println("Equal using equals method");
} else {
System.out.println("Not equal using equals method");
}
}
}
输出为:1. og 很高兴 2. og 很高兴 3. 使用相等运算符不等于 4. 使用 equals 方法等于
P.S。这是子字符串方法源代码:
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);
}
P.S。这个问题已被标记为已被多人提问和回答,但我在 Stack Overflow 上找不到一个实例,其中有人真正解释了为什么 substring(0) 的计算结果为真。
答案就在你的问题本身。
尝试执行以下操作:
String str1 = "The dog was happy";
String str2 = "The dog was happy";
if (str1 == str2)
{
System.out.println("Equal using equality operator");
}
else
{
System.out.println("Not equal using equality operator");
}
你会得到"Equal using equality operator"。原因是您已将 str1 和 str2 都声明为字符串文字,并且内部池的概念适用。
现在,当您根据字符串 class 定义执行 str1.substring(5) 时,它 returns 是一个对象,而不是文字。因此 == 给出了错误的结果。
字符串class子串方法:
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
如果您希望 == 对子字符串起作用,请对您的子字符串使用 intern() 方法。
变化:
if (str1.substring(5) == str2.substring(5))
到
if (str1.substring(5).intern() == str2.substring(5).intern())
一个很好的文档来理解字符串创建和池化的细节:https://www.journaldev.com/797/what-is-java-string-pool