我正在尝试学习使用StringBuilder类与回文的例子,并写了这个:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
StringBuilder word = new StringBuilder(scanner.nextLine());
System.out.println(word);
StringBuilder reverseWord = word.reverse();
System.out.println(reverseWord);
if(word.toString().equals(reverseWord.toString())) {
System.out.println("yes");
}else {
System.out.println("no");
}
}
程序不断给我的结果是&;是&;但我不明白为什么?很明显,我的if块有问题,但我看不出是什么。
当你调用word.reverse()
时,它不会返回一个新的反向StringBuilder
实例。相反,它颠倒了StringBuilder
内部的元素,因此word
和reverseWord
StringBuilder
对象都具有颠倒顺序的字符。您不需要使用两个StringBuilder
对象。你只需要找到一个相反的,然后你可以把它和原来的比较,像这样:
String input = scanner.nextLine();
StringBuilder reverseWordBuilder = new StringBuilder(input);
String reversedWord = reverseWordBuilder.reverse().toString();
if(input.equals(reversedWord)) {
System.out.println("yes");
} else {
System.out.println("no");
}
对word.reverse()
的调用返回this
,而不是StringBuilder的新实例-因此您将看到word == reverseWord
.
你可以确认这一点,如果你移动System.out.println(word);
下的word.reverse()
调用,两行将打印相同的(反向)值。
StringBuilder
ismutable,这意味着您可以在不创建新实例的情况下更改其状态。String
是一个不可变的这意味着每次当你做一些改变时,它会在heap
中创建一个新的对象,它的地址不同。
Builder
StringBuilder
紧跟构建器模式。
Builder模式方法主要实现为返回对同一对象的引用(如return this
)。
在您的示例中,word.reverse()
将返回对同一对象的引用。
虽然有两个不同的引用变量,但它们都指向同一个对象,因此任何类似的比较都将返回true
为了更清楚,word == reverseWord
也将是true
当您反转时,您正在反转单词然后返回它,因此在最后单词与reversedWord相同。下面是一个例子:
StringBuilder word = new StringBuilder("hello");
StringBuilder reverseWord = word.reverse();
System.out.println(word); // Output: olleh
System.out.println(reverseWord); // Output: olleh
参见文档:https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html
- 当一个新的
StringBuilder
对象被创建时,它被放置在Heap Memory
- 在对
StringBuilder
对象进行操作期间,不会像经典String
那样创建新对象,因此在任何操作之后,实际对象都会被修改。
解释回文场景:
-
在这种情况下,假设
word = "AS0A"
。在Heap
中,假设它指向@00AAXX
对象。 -
当你调用
word.reverse()
时,它会反转"AS0A"比;"A0SA"并在Heap
中更新word
对象。现在,word = "A0SA"
在Heap
. -
现在,当您将
word.reverse()
赋值给StringBuilder reverseWord
时,这次不会创建新的对象。reverseWord
只是点@00AAXX
(word
对象的位置)。 -
如果你想在堆中创建一个新对象。你应该使用
new
:
StringBuilder reverseWord = new StringBuilder(word.reverse());
但是,
new object
并不能解决这个问题,因为word
对象的值已经被修改了。所以,在调用reverse之前,存储值的位置不同。然后比较。
修改后的代码块:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
StringBuilder word = new StringBuilder(scanner.nextLine());
System.out.println(word);
String wordString = word.toString();
StringBuilder reverseWord = new StringBuilder(word.reverse());
System.out.println(reverseWord);
System.out.println(word);
if(wordString.equals(reverseWord.toString())) {
System.out.println("yes");
}else {
System.out.println("no");
}
}