在 Java 中将 StringBuilder 用于回文示例

问题描述

我正在尝试使用带有回文示例的 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() 的调用返回 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");
}
,

StringBuilder可变的,这意味着您可以更改他的状态而无需创建它的新实例。 String 是一个不可变,这意味着每次进行更改时,都会在 heap 中创建一个具有不同地址的新对象。

,

生成器

StringBuilder 紧跟构建器模式。

构建器模式方法主要用于返回对同一对象的引用(如 return this)。

在您的示例中,word.reverse() 将返回对同一对象的引用。

虽然有 2 个不同的引用变量,但它们都指向同一个对象,因此任何类似的比较都将返回 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

查看文档:{​​{3}}

,
  • 当一个新的 StringBuilder 对象被创建时,它被放置在 Heap Memory 中。
  • 在对 StringBuilder 对象进行操作期间,不会像经典的 String 那样创建新对象,因此在任何操作之后,都会修改实际对象。

解释回文场景:

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

  2. 当您调用 word.reverse() 时,它会反转“AS0A”>“A0SA”。并更新 word 中的 Heap 对象。现在,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");
        }
}