33

Well I have two StringBuilder objects, I need to compare them in Java. One way I know I can do is

sb1.toString().equals(sb2.toString());

but that means I am creating two String objects, is there any better way to compare StringBuilder objects. Probably something where you do not need to create additional objects?

ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
user1344389
  • 437
  • 1
  • 6
  • 9
  • 10
    I'm surprised that `StringBuilder` doesn't declare its own `equals` method. – Jeffrey Jun 13 '12 at 02:25
  • what you are doing is the best way to do this, barring exceeding large `String` objects. –  Jun 13 '12 at 02:31

4 Answers4

44

As you apparently already know, StringBuilder inherits equals() from java.lang.Object, and as such StringBuilder.equals() returns true only when passed the same object as an argument. It does not compare the contents of two StringBuilders!

If you look at the source, you'll conclude that the most efficient comparison (that didn't involve creating any new objects) would be to compare .length() return values, and then if they're the same, compare the return values of charAt(i) for each character.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
  • 1
    FYI, `charAt(i)` is a thin veneer (with parameter bounds checking) over `value[i]`, where `value` is the `char[]` holding the current String, so yeah - this is the fastest way. And may I add, it is retarded that in 2012 we all need to implement this instead of it being inside the `StringBuilder` class with a tight loop impl. Is there not an apache commons static method that does this? – Bohemian Jun 13 '12 at 02:49
  • @Bohemian, I am sure there is something in Apache Commons, but I am always loath to ask people to pull that package in for just one method like this. – Ernest Friedman-Hill Jun 13 '12 at 02:57
  • I don't hold with that, because *the best code is someone else's code*, so if there's a proxy standard library out there (even if a little lame), I always recommend using it. Also, once they get a taste for commons methods, they will find more uses for them... `less code == good`. – Bohemian Jun 13 '12 at 04:08
  • If only stringbuilder allowed us to get a reference of the underlying char[] buffer that resides in AbstractStringBuilder so we could then use Arrays.equals(char[], char[]) on it :P – george_h Jun 13 '12 at 04:55
  • Strange there is no method to compare the content of stringBuilder objects – aless80 Jun 10 '18 at 13:18
27

Since Java 11, StringBuilder implements Comparable, so you can use a compareTo method for the equality test:

System.out.println(sb1.compareTo(sb2) == 0);
Derrick
  • 3,669
  • 5
  • 35
  • 50
ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
3

Two StringBuilder objects are never equal. Use .toString() to get the string representation for both the objects and then use .equals() to compare the objects. This way equals() method from the String class gets invoked that compares the string value of the objects instead of comparing the memory location.

StringBuilder a= new StringBuilder("HELLO JAVA");
StringBuilder b= new StringBuilder("HELLO JAVA");
if (a.toString().equals(b.toString())){
System.out.println("Objects are equal");
}
prats
  • 39
  • 1
1

A solution without new allocations would be to compare first at length, and if it differs, then char by char. This is more efficient and faster than performing a compare via a toString() on the StringBuilder call, which would allocate a new string.

The next snipped assumes both parameters aren't null neither the same object instance:

public boolean compare(final StringBuilder left, final StringBuilder right) {
    final int length = left.length();

    if (length != right.length())
        return false;

    for (int index = 0; index < length; index++) {
        if (left.charAt(index) != right.charAt(index))
            return false;
    }

    return true;
}
PerracoLabs
  • 16,449
  • 15
  • 74
  • 127