在 Java 中将 StringBuilder 用于回文示例
Using StringBuilder for Palindrome Example in Java
我正在尝试通过回文示例学习使用 StringBuilder class 并编写了以下内容:
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()
returns this
而不是 StringBuilder 的新实例 - 所以你会看到 word == reverseWord
.
如果将调用下方的 System.out.println(word);
移动到 word.reverse()
并且两行将打印相同的(反向)值,则可以确认这一点。
当您调用 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");
}
StringBuilder
是 mutable,这意味着你可以改变他的状态而不用创建它的新实例。 String
是一个 不可变的 ,这意味着每次您进行一些更改时,都会在 heap
.
中创建一个具有不同地址的新对象
建设者
StringBuilder
紧跟建造者模式。
构建器模式方法主要实现为 return 对同一对象的引用(如 return this
)。
在您的示例中,word.reverse()
将 return 引用同一对象。
虽然有 2 个不同的引用变量,但它们都指向同一个对象,因此任何类似的比较都会 return 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");
}
}
我正在尝试通过回文示例学习使用 StringBuilder class 并编写了以下内容:
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()
returns this
而不是 StringBuilder 的新实例 - 所以你会看到 word == reverseWord
.
如果将调用下方的 System.out.println(word);
移动到 word.reverse()
并且两行将打印相同的(反向)值,则可以确认这一点。
当您调用 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");
}
StringBuilder
是 mutable,这意味着你可以改变他的状态而不用创建它的新实例。 String
是一个 不可变的 ,这意味着每次您进行一些更改时,都会在 heap
.
建设者
StringBuilder
紧跟建造者模式。
构建器模式方法主要实现为 return 对同一对象的引用(如 return this
)。
在您的示例中,word.reverse()
将 return 引用同一对象。
虽然有 2 个不同的引用变量,但它们都指向同一个对象,因此任何类似的比较都会 return 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");
}
}