为什么 HashMap 允许重复,而 StringBuilder 不能正确反转?

Why does HashMap allow duplicates and StringBuilder does not reverse properly?

HashMap 不应允许重复,而 StringBuilder.reverse() 不能正常工作。为什么?

String s = "abba";
static int myMethod(String s) {
        int counter = 0;
        Map<StringBuilder, StringBuilder> map = new HashMap<>();
        for (int j = 0; j <= s.length(); j++) {
            for (int i = j + 1; i <= s.length(); i++) {
                StringBuilder sb = new StringBuilder(s.substring(j, i));
                map.put(sb, sb.reverse());
            }
        }
        System.out.println("map " + map);
        return counter;
    }

输出:

map {bba=bba, ba=ba, b=b, a=a, a=a, ab=ab, abb=abb, abba=abba, b=b, bb=bb}

您不应将 StringBuilder 存储在 HashMap 中,因为与 String 不同,它不会根据其内容实现 equals()hashCode() 方法(它从 Object 继承了它们)。 StringBuilder 的两个不同实例永远不会相等。为了使程序正常运行并防止重复,存储 String 改为:

String s = "abba";
int counter = 0;
Map<String, String> map = new HashMap<>();
for (int j = 0; j <= s.length(); j++) {
     for (int i = j + 1; i <= s.length(); i++) {
          StringBuilder sb = new StringBuilder(s.substring(j, i));
          StringBuilder reverse = sb.reverse();
          map.put(s.substring(j, i), reverse.toString());
     }
}
System.out.println("map " + map);

输出:

map {abb=bba, bb=bb, bba=abb, a=a, ab=ba, b=b, abba=abba, ba=ab}

HashMap 不允许重复。但问题在于如何确定这些重复项,以及您可能认为的原因。

它使用 hashCode()equals() 来确定两个事物是否相同。 StringBuilder 不覆盖任何一个,因此使用 Object 中基于身份的实现。因此,StringBuilder 的两个不同实例 - 无论内部缓冲区的内容如何 - 都是不相等的。


reverse()StringBuilder 反转到位。因此,sbsb.reverse() 是相同的 StringBuilder

显然,同一个实例只能有一个顺序的字符。您在这里看到的是将反转的字符串存储为键和值。