在 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 中反转元素,因此 wordreverseWord 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");
}

StringBuildermutable,这意味着你可以改变他的状态而不用创建它的新实例。 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 那样创建新对象,因此在任何操作之后,都会修改实际对象。

解释回文情景:

  1. 在这种情况下,假设word = "AS0A"。在Heap中,假设它指向@00AAXX对象。

  2. 当您调用 word.reverse() 时,它会反转“AS0A”>“A0SA”。并更新 Heap 中的 word 对象。现在,word = "A0SA"Heap.

  3. 现在,当您将 word.reverse() 分配给 StringBuilder reverseWord 时,这次不会创建新对象。 reverseWord 只需指向 @00AAXXword 对象的位置)。

  4. 如果你想在堆中创建一个新对象。您应该使用 new 然后:

StringBuilder reverseWord = new StringBuilder(word.reverse());
  1. 但是,new object 并没有解决这个问题,因为 word 对象的值已经被修改了。

  2. 所以,在调用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");
        }
}