Why no equals method in String buffer

We all know StringBuffer does not override the equals method. Now there should be a specific reason why java did not override the equals method. Anybody knows what that reason might be?
[192 byte] By [Kaputaboa] at [2007-10-2 8:17:12]
# 1

The equals() method usually indicates whether two subjects are the same object, and this is relied upon here and there in the standard classes. For example, a Set cannot contain two references to the same object (as defined by equals()).

The fact that equals() is overridden in String is kind of a special case, which is safe because a String is utterly immutable, and convenient because Strings are used in much the same fashion as primitives in many cases. It is pretty hard to imagine a case in which a person would need to know whether two Strings with the same content were the same object.

Plus it is childishly easy to compare the contents of two StringBuffers or StringBuilders without overriding equals...

StringBuilder bob = new StringBuilder("bob");

StringBuilder joe = new StringBuilder("joe");

System.out.println(bob.toString().equals(joe.toString())); // prints "false"

Drake

Drake_Duna at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 2
StringBuffer is mutable and as such it would be inappropriate for equals() to be implemented based upon contents. It would then be possible, for example, to break the contract of Set by adding two StringBuffers with different contents and then changing the contents to be identical.
kablaira at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

> StringBuffer is mutable and as such it would be

> inappropriate for equals() to be implemented based

> upon contents. It would then be possible, for

> example, to break the contract of Set by adding two

> StringBuffers with different contents and then

> changing the contents to be identical.

Do you mean that any mutable class should NOT redefine equals?

Obviously it's dangerous to stuff mutable objects in any collection (Set, Map) that rely on object equality, but usage of equals() is not restrained to Collections.

OTOH, it is recommended to make hashcode() consistent with equals(), and hashcode() is definitely intended for collections...

jdupreza at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

java has two versions of the equals() method, the original one, in the object class, does reference/address comparison, same as what == does, the other does the value compariosn, such as the one in the string class.

value comparison compares values, the string class has a simple value: strings only, while the stringbuffer has a more complex values: the string itself, its capacity, etc, and it is therefore senseless to do value comparison on a stringbuffer object, it does not do anything useful in any sense.

jdupreza at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

> > StringBuffer is mutable and as such it would be

> > inappropriate for equals() to be implemented based

> > upon contents. It would then be possible, for

> > example, to break the contract of Set by adding

> two

> > StringBuffers with different contents and then

> > changing the contents to be identical.

>

> Do you mean that any mutable class should NOT

> redefine equals?

That's not what I said. I said it would inappropriate for a StringBuffer to redefine equals based upon it's contents. Don't extract an arbitrary rule from that narrow context.

> Obviously it's dangerous to stuff mutable objects in

> any collection (Set, Map) that rely on object

> equality, but usage of equals() is not restrained to

> Collections.

> OTOH, it is recommended to make hashcode() consistent

> with equals(), and hashcode() is definitely intended

> for collections...

It's not just used for Collections, but overriding equals() is also something that shouldn't be done carelessly. You have to consider not just that they should logically be the same, but that Collections and any other place that uses it in the expected manner should consider them the same as well. It also means that inevitably any Set with mutable objects whose equals() methods may return differently when it has mutated is not guaranteed to obey the contract of Set. I prefer to keep logical comparisons out of equals() for this very reason, but I haven't ever said that doing so is inherently "bad".

kablaira at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

> java has two versions of the equals() method, the

> original one, in the object class, does

> reference/address comparison, same as what == does,

> the other does the value compariosn, such as the one

> in the string class.

>

> value comparison compares values, the string class

> has a simple value: strings only, while the

> stringbuffer has a more complex values: the string

> itself, its capacity, etc, and it is therefore

> senseless to do value comparison on a stringbuffer

> object, it does not do anything useful in any sense.

It would be trivially easy to override equals() such that it returns true if two StringBuffer instances were identical in state and it would in fact be quite useful. It would also break Collections, which is probably why it's not done, and would also not be consistent when the state changes. The key difference in a String is in fact that it is immutable and as such it's state will never change and it will always be consistent over time within our (assumed) context.

kablaira at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 7

Really, there is no good reason for not overriding equals in StringBuffer/Builder. I mean, okay, it's trivially easy to test for equality, but that's true of a lot of things. It's pretty trivial to code my own linked list, but I like having the library version there anyway. This is the sort of thing libraries are for: having code I don't want to write over and again.

Whatever argument you could maybe think up against it, I offer you this:

Can you, honestly, think of a different way you'd want to test equality between StringBuffers? Have you ever put a StringBuffer in a collection like a Set - i.e. would it break your code if StringBuffer had a real .equals? If you were testing for equality between StringBuffers and you wanted to test for identity, would you really use myBuffer.equals(thatBuffer), and not myBuffer == thatBuffer? And lastly, don't you expect two buffers holding the same thing to be equal? All the collections do that (even though the interfaces don't require it), and they're certainly mutable.

et cetera

~Cheers

Adeodatusa at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

> Really, there is no good reason for not overriding

> equals in StringBuffer/Builder. I mean, okay, it's

> trivially easy to test for equality, but that's true

> of a lot of things. It's pretty trivial to code my

> own linked list, but I like having the library

> version there anyway. This is the sort of thing

> libraries are for: having code I don't want to write

> over and again.

>

> Whatever argument you could maybe think up against

> it, I offer you this:

> Can you, honestly, think of a different way you'd

> want to test equality between StringBuffers? Have you

> ever put a StringBuffer in a collection like a Set -

> i.e. would it break your code if StringBuffer had a

> real .equals? If you were testing for equality

> between StringBuffers and you wanted to test for

> identity, would you really use

> myBuffer.equals(thatBuffer), and not myBuffer ==

> thatBuffer? And lastly, don't you expect two buffers

> holding the same thing to be equal? All the

> collections do that (even though the interfaces don't

> require it), and they're certainly mutable.

>

I have certainly used equals() on String thousands of times.

And I have certainly used StringBuffer many times as well.

And yet I have never wanted to use equals() on two StringBuffers. (I have never wanted to use StringBuffer in a collection either.)

So for me the issue is meaningless.

Anyone that thinks it is important can look for an RFE in the bug database or add their own. If one already exists it might have a comment explaining why it is not considered necessary by the VM developers.

jschella at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 9

> Really, there is no good reason for not overriding

> equals in StringBuffer/Builder. I mean, okay, it's

> trivially easy to test for equality, but that's true

> of a lot of things. It's pretty trivial to code my

> own linked list, but I like having the library

> version there anyway. This is the sort of thing

> libraries are for: having code I don't want to write

> over and again.

What exactly is the "good" reason for having it? I don't accept "So I don't have to type toString()" as a good reason if that's all there is.

> Whatever argument you could maybe think up against

> it, I offer you this:

> Can you, honestly, think of a different way you'd

> want to test equality between StringBuffers? Have you

> ever put a StringBuffer in a collection like a Set -

> i.e. would it break your code if StringBuffer had a

> real .equals? If you were testing for equality

> between StringBuffers and you wanted to test for

> identity, would you really use

> myBuffer.equals(thatBuffer), and not myBuffer ==

> thatBuffer? And lastly, don't you expect two buffers

> holding the same thing to be equal? All the

> collections do that (even though the interfaces don't

> require it), and they're certainly mutable.

>

> et cetera

>

> ~Cheers

Yes, I can: identity, case-(in)sensitive logical comparisons, capacity, case-(in)sensitive weighted logcial comparisons, case-(in)sensitive logical comparisons with vowels dropped, etc. You've got to remember that overriding equals() isn't something to be done arbitrarily. When you override equals() you define what exactly is considered the "same" in a Set and you impose that upon the clients trying to use the library. It can be done safely with an immutable String but a mutable StringBuffer is another story entirely. I believe this behavior would be beyond the responsibility of a StringBuffer. If you find a common need to make logical comparisons a much better solution is to write a wrapper that will deal with it, that way each type of logical comparison may have it's own wrapper. For example a CaseSensitiveStringBuffer (I know the name sucks) might wrap a StringBuffer and provide an equals() that does the logical comparison you want.

kablaira at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 10

> It would be trivially easy to override equals() such

> that it returns true if two StringBuffer instances

> were identical in state and it would in fact be quite

> useful.

what do you mean two stringbuffer objs are identical in state?

> It would also break Collections,

it would not break collections, unless of course you write baad code, which is likely when you are doing it.

> which is

> probably why it's not done, and would also not be

> consistent when the state changes.

that can not be a reason for whatever you are saying. the fact the matter is, there are many times you would have to override the equal() to provide value copmparison on a particular identifier value for it to work properly once in a set/collections. you would probablly have to override the hascod() as well.

> The key

> difference in a String is in fact that it is

> immutable and as such it's state will never change

> and it will always be consistent over time within our

> (assumed) context.

that dont matter.

kablaira at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

> > It would be trivially easy to override equals()

> such

> > that it returns true if two StringBuffer instances

> > were identical in state and it would in fact be

> quite

> > useful.

>

> what do you mean two stringbuffer objs are identical

> in state?

Which part don't you understand: what object state is or what identical means? If it's the former get an introductory OO book. If it's the latter get a dictionary.

> > It would also break Collections,

>

> it would not break collections, unless of course you

> write baad code, which is likely when you are doing

> it.

>

> > which is

> > probably why it's not done, and would also not be

> > consistent when the state changes.

>

> that can not be a reason for whatever you are saying.

> the fact the matter is, there are many times you

> would have to override the equal() to provide value

> copmparison on a particular identifier value for it

> to work properly once in a set/collections. you would

> probablly have to override the hascod() as well.

Why can't it be a reason? What do you mean there are "many times you would have to override the equal()"? If you're talking about other classes then so what? We're talking about this class and whether or not there may be cases where this is desired in other classes the question is whether or not it's desired in this class. I submit that the authors may have felt it wasn't and I've already supplied reasons it wouldn't be.

> > The key

> > difference in a String is in fact that it is

> > immutable and as such it's state will never change

> > and it will always be consistent over time within

> our

> > (assumed) context.

>

> that dont matter.

Yes, it does, because it will never change is equivalent to identity.

kablaira at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 12
> ... because it will never change is> equivalent to identity.thats why oftentimes the hashcode is used by many equals()
kablaira at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 13

> > ... because it will never change is

> > equivalent to identity.

>

> thats why oftentimes the hashcode is used by many

> equals()

There is an explicit contract between equals() and hashcode() and if that isn't followed then a class can not be used in a hashing collection.

jschella at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 14

The general contract of hashCode is:

Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

jschella at 2007-7-16 22:15:34 > top of Java-index,Other Topics,Patterns & OO Design...
# 15

> The general contract of hashCode is:

>

> Whenever it is invoked on the same object more than

> once during an execution of a Java application, the

> hashCode method must consistently return the same

> integer, provided no information used in equals

> comparisons on the object is modified. This integer

> need not remain consistent from one execution of an

> application to another execution of the same

> application.

>

> If two objects are equal according to the

> equals(Object) method, then calling the hashCode

> method on each of the two objects must produce the

> same integer result.

>

> It is not required that if two objects are unequal

> according to the equals(java.lang.Object) method,

> then calling the hashCode method on each of the two

> objects must produce distinct integer results.

> However, the programmer should be aware that

> producing distinct integer results for unequal

> objects may improve the performance of hashtables.

Thank you for posting what the rest of us already know. Now do you have anything meaningful to add?

kablaira at 2007-7-20 19:41:42 > top of Java-index,Other Topics,Patterns & OO Design...
# 16

> Thank you for posting what the rest of us already

> know. Now do you have anything meaningful to add?

just a little bit: i wont be surprised if you have read it many times already, but the question is: did you comprehend it? based on what you have been saying, you probably did not.

kablaira at 2007-7-20 19:41:42 > top of Java-index,Other Topics,Patterns & OO Design...
# 17

> just a little bit: i wont be surprised if you have

> read it many times already, but the question is: did

> you comprehend it? based on what you have been

> saying, you probably did not.

Why don't you amuse us with your thoughts on how this pertains to the absence of a StringBuffer specific implementation of equals then Daff?

dcmintera at 2007-7-20 19:41:42 > top of Java-index,Other Topics,Patterns & OO Design...
# 18

> > Thank you for posting what the rest of us already

> > know. Now do you have anything meaningful to add?

>

> just a little bit: i wont be surprised if you have

> read it many times already, but the question is: did

> you comprehend it? based on what you have been

> saying, you probably did not.

It indirectly supports exactly what I said about StringBuffer. If you override equals() to return the result of a logical comparison instead of leaving Object's implementation in place you have to change the hashCode() implementation too. Then suddenly every StringBuffer becomes the "same" as every other StringBuffer that has the same contents. It imposes an arbitrary restriction in it's use upon the client rather than leaving the distinction of how a StringBuffer's contents should be compared to the client instead. Considering the client is the only one with knowledge of what the specific context it is being used in, and as such the only one with knowledge of how one StringBuffer should be logically compared to another, it would be horribly inappropriate to add that functionality to StringBuffer itself.

kablaira at 2007-7-20 19:41:42 > top of Java-index,Other Topics,Patterns & OO Design...
# 19
> It indirectly supports exactly what I said about> StringBuffer. of ocurse, mr blair, very indirectly, guess you need to twist it quite a bit:)
kablaira at 2007-7-20 19:41:42 > top of Java-index,Other Topics,Patterns & OO Design...
# 20

> > It indirectly supports exactly what I said about

> > StringBuffer.

>

> of ocurse, mr blair, very indirectly, guess you need

> to twist it quite a bit:)

Daff, you're as thick as they come. If you've got something to say that's not pasted in from the API documents, get it off your smug chest so we can rip it to shreds. Or learn to speak fucking English and make a coherent point for once in your wasted life.

dcmintera at 2007-7-20 19:41:42 > top of Java-index,Other Topics,Patterns & OO Design...
# 21

> > It indirectly supports exactly what I said about

> > StringBuffer.

>

> of ocurse, mr blair, very indirectly, guess you need

> to twist it quite a bit:)

I didn't have to twist anything bonehead. It's indirect becuase it's part of the premise the entire argument was built on. It may have been more accurate to say it supports the premise of what I said, but either way you still won't know what the hell we're talking about and will still spit out random irrelevent jibberish as you always do.

kablaira at 2007-7-20 19:41:42 > top of Java-index,Other Topics,Patterns & OO Design...
# 22

> Or learn to speak fucking English

> and make a coherent point for once in your wasted

> life.

daav:

read more of this thread, its not too long, and your englsh is good, it should not take up too much of your effert to read it, right? i can not repeat it for you. its not a too exciting topic.

kablaira at 2007-7-20 19:41:42 > top of Java-index,Other Topics,Patterns & OO Design...
# 23

> > Or learn to speak fucking English

> > and make a coherent point for once in your wasted

> > life.

>

> daav:

>

> read more of this thread, its not too long, and your

> englsh is good, it should not take up too much of

> your effert to read it, right? i can not repeat it

> for you. its not a too exciting topic.

That didn't actually address anything he said, least of all the part you quoted. Your grand contribution to this thread thus far was to claim overridding equals() would be too hard and not do anything "useful". We've already gone over why those statements are idiotic, though you apparently didn't understand it because you either don't know what state is or you dont' know what identical means.

'tard.

kablaira at 2007-7-20 19:41:42 > top of Java-index,Other Topics,Patterns & OO Design...
# 24

>Your grand contribution

> to this thread thus far was to claim overridding

> equals() would be too hard and not do anything

> "useful".

it is hard to do so and there is no reason to do that.

> We've already gone over why those

> statements are idiotic, though you apparently didn't

> understand it because you either don't know what

> state is or you dont' know what identical means.

>

and you have not englitened me yet.

kablaira at 2007-7-20 19:41:42 > top of Java-index,Other Topics,Patterns & OO Design...
# 25
and you said it is easy to do so, then post your grand code.
kablaira at 2007-7-20 19:41:43 > top of Java-index,Other Topics,Patterns & OO Design...
# 26

> and you said it is easy to do so, then post your

> grand code.

Off the cuff? It might look something like

@Override

public boolean equals(final Object o) {

// Same instance.

if (this == o)

return true;

if (o instanceof AbstractStringBuilder) {

if (((AbstractStringBuilder)o).length() != count) {

// Not even the same length, don't bother iterating.

return false;

}

final char val[] = ((AbstractStringBuilder)o).getValue();

for (int i = 0; i < count; i++) {

if (value[i] != val[i])

return false;

}

// Same length and contents, return true.

return true;

}

// Wasn't an instance of AbstractStringBuilder.

return false;

}

String already has contentEquals() which effectively does exactly this. I don't know what you find so difficult in the matter, it's a simple comparison of a specified length of two char[].

kablaira at 2007-7-20 19:41:43 > top of Java-index,Other Topics,Patterns & OO Design...
# 27
> it is hard to do so and there is no reason to do> that.It's easy and it's already been done, just not by overridding equals().> and you have not englitened me yet.No, I pointed you to the appropriate resources to educate yourself.
kablaira at 2007-7-20 19:41:43 > top of Java-index,Other Topics,Patterns & OO Design...
# 28
> and you have not englitened me yet.For much the same reason that rocks don't get enlightened.
dcmintera at 2007-7-20 19:41:43 > top of Java-index,Other Topics,Patterns & OO Design...
# 29

> String already has contentEquals() which effectively

> does exactly this. I don't know what you find so

> difficult in the matter, it's a simple comparison of

> a specified length of two char[].

ok, then

StringBuffer buffA = new StringBuffer();

StringBuffer buffB = new StringBuffer(10000);

what will your grand equlas return on buffA and buffB? is buffA.equals(buffB)?

dcmintera at 2007-7-20 19:41:43 > top of Java-index,Other Topics,Patterns & OO Design...
# 30
> > and you have not englitened me yet.> > For much the same reason that rocks don't get> enlightened.arent you happy that there is a new member on planet chicken?
at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 31
> arent you happy that there is a new member on planet> chicken?Why are you so interested in chickens? Does it have a double meaning in your language?
dcmintera at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 32
> > arent you happy that there is a new member on> planet> > chicken?> > Why are you so interested in chickens? Does it have a> double meaning in your language?they have lots of meanings, all of them are imaginary.
dcmintera at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 33

> ok, then

>

> > StringBuffer buffA = new StringBuffer();

> StringBuffer buffB = new StringBuffer(10000);

>

>

> what will your grand equlas return on buffA and

> buffB? is buffA.equals(buffB)?

Yes, they're both empty. Their contents is identical, though the capacity is different. If you think it should check capacity as well that's another trivial line of code. What point are you trying to make or are you so dense you don't even understand the code I posted?

kablaira at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 34
I meant yes as in it will return true. It will find they are both AbstractStringBuilders with a count of 0 and then end up bypassing the loop since there's nothing to check and return true.
kablaira at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 35
> I meant yes as in it will return true. It will find> they are both AbstractStringBuilders with a count of> 0 and then end up bypassing the loop since there's> nothing to check and return true.Which is certainly what I would expect it to do.
jschella at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 36

> > I meant yes as in it will return true. It will

> find

> > they are both AbstractStringBuilders with a count

> of

> > 0 and then end up bypassing the loop since there's

> > nothing to check and return true.

>

> Which is certainly what I would expect it to do.

but why? why do you want to have this equals()? how would i associate this equals() to stringbuffer object? do not you have anything better to do?

jschella at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 37

> > > I meant yes as in it will return true. It will

> > find

> > > they are both AbstractStringBuilders with a

> count

> > of

> > > 0 and then end up bypassing the loop since

> there's

> > > nothing to check and return true.

> >

> > Which is certainly what I would expect it to do.

>

> but why? why do you want to have this equals()? how

> would i associate this equals() to stringbuffer

> object? do not you have anything better to do?

I expect capacity to have nothing to do with the concept of equality for these entities.

jschella at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 38

> > > > I meant yes as in it will return true. It

> will

> > > find

> > > > they are both AbstractStringBuilders with a

> > count

> > > of

> > > > 0 and then end up bypassing the loop since

> > there's

> > > > nothing to check and return true.

> > >

> > > Which is certainly what I would expect it to do.

> >

> > but why? why do you want to have this equals()?

> how

> > would i associate this equals() to stringbuffer

> > object? do not you have anything better to do?

>

> I expect capacity to have nothing to do with the

> concept of equality for these entities.

the equals() can be implemented any way you want; but each time you do it, you should have a reason for doing this. the capacity value may not matter in certain cases but the point is why do you want to override the ref comparison just for string value comparison? why? in particular, why do you want to do this for the stringbuffer obj?

jschella at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 39

>

> the equals() can be implemented any way you want; but

> each time you do it, you should have a reason for

> doing this. the capacity value may not matter in

> certain cases but the point is why do you want to

> override the ref comparison just for string value

> comparison? why? in particular, why do you want to do

> this for the stringbuffer obj?

I was commenting on the results of the comparision. The capacity should have no impact on the result of the comparison. And it doesn't. Thus it is doing it correctly.

jschella at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 40

> the equals() can be implemented any way you want; but

> each time you do it, you should have a reason for

> doing this. the capacity value may not matter in

> certain cases but the point is why do you want to

> override the ref comparison just for string value

> comparison? why? in particular, why do you want to do

> this for the stringbuffer obj?

The original question was why Sun didn't implement it this way. Your answer was it's "too hard" but I've already shown you how trivial it is. Your other answer was it won't do anything "useful", but a logical comparison is very useful and already exists precisely because it is useful, so that's nonsense.

Now I've already offered up a few reasons why Sun may have chosen to not implement this through equals() and why I believe equals() is the wrong place for this. Do you have one?

kablaira at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 41

> but why? why do you want to have this equals()? how

> would i associate this equals() to stringbuffer

> object? do not you have anything better to do?

It's what he would expect a logical comparison of two StringBuffers to return. That does not imply it means he thinks a logical comparison should be done in equals() in the first place.

kablaira at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 42

> how

> would i associate this equals() to stringbuffer

> object? do not you have anything better to do?

Are you that stupid? It would be part of AbstractStringBuilder. This has nothing to do with whether or not it should be done but is merely addressing your points which were completely inaccurate.

kablaira at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 43

> > how

> > would i associate this equals() to stringbuffer

> > object? do not you have anything better to do?

>

> Are you that stupid? It would be part of

> AbstractStringBuilder. This has nothing to do with

> whether or not it should be done but is merely

> addressing your points which were completely

> inaccurate.

so this one works fine on stringbuffer? of course, even jschell says so too. now it appears the previosly advocated notion that it is needs to be an immutable does not stand any more. is this right, mr k blair? thanks for your efforts to disapproving yourself. happy new year:)

kablaira at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 44

> so this one works fine on stringbuffer? of course,

> even jschell says so too. now it appears the

> previosly advocated notion that it is needs to be an

> immutable does not stand any more. is this right, mr

> k blair? thanks for your efforts to disapproving

> yourself. happy new year:)

Where did kablair say that?

jschella at 2007-7-20 19:41:47 > top of Java-index,Other Topics,Patterns & OO Design...
# 45
> Where did kablair say that?that's all he was saying here. i am surprised that you missed it. kind of fun, self destrcution:)
at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 46

> so this one works fine on stringbuffer? of course,

> even jschell says so too. now it appears the

> previosly advocated notion that it is needs to be an

> immutable does not stand any more. is this right, mr

> k blair? thanks for your efforts to disapproving

> yourself. happy new year:)

You don't seem to understand the difference between whether or not it can be done and whether or not it should be done.

The OP wants to know why the author's didn't include it.

You claimed it was too hard and not useful. I disproved that by demonstrating how trivial it is and pointing out ways in which it is useful.

I claimed it was easy to do but not appropriate. How two StringBuffers should be compared is dependent upon context and use. The client knows the context and use, the StringBuffer does not. Overridding equals to return a logical result would impose an arbitrary rule on the client. Why should the StringBuffer make assumptions about that which it cannot know rather than letting the client, who does actually know, decide for itself?

These concerns are not an issue with String because it is immutable.

jschell is right that I never said anything about immutable in the context in which you are using it[/i[. It's no surprise you don't understand this, considering you have little understanding of Java, the English language or simple logic.

kablaira at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 47
> > Where did kablair say that?> > that's all he was saying here. i am surprised that> you missed it. kind of fun, self destrcution:)As I thought - kablair didn't say it.
jschella at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 48

> > > Where did kablair say that?

> >

> > that's all he was saying here. i am surprised that

> > you missed it. kind of fun, self destrcution:)

>

> As I thought - kablair didn't say it.

sir k blair said the following as the third post of this thread:

"StringBuffer is mutable and as such it would be inappropriate for equals() to be implemented based upon contents. It would then be possible, for example, to break the contract of Set by adding two StringBuffers with different contents and then changing the contents to be identical."

jschella at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 49

I will, regretfully, have to concede DaFei's point here. If the same logic for immutability was followed (in terms of breaking the contract of Set), then I could never place java.util.Date in a Collection either. I can easily mutate its value via setTime().

However, I can easily see where Kablair is coming from. Quoted from the API docs for Set:

Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element.

So, both people are right. One is allowed to use mutable objects in a Set, though Set will no longer be able to guarantee uniqueness of mutable elements. In effect, the contract no longer applies and the behavior is not specified. My bottom line take on that: you can use mutable objects, just be more careful than normal.

- Saish

Saisha at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 50

> I will, regretfully, have to concede DaFei's point

> here. If the same logic for immutability was

> followed (in terms of breaking the contract of Set),

> then I could never place java.util.Date in a

> Collection either. I can easily mutate its value via

> setTime().

>

your english would have been perfect had you used the word 'gladly' instead of 'regretfully', unless of course you are admitting with regret that you did not following my teachings.

> However, I can easily see where Kablair is coming

> from. Quoted from the API docs for Set:

>

> Note: Great care must be exercised if mutable

> objects are used as set elements. The behavior of a

> set is not specified if the value of an object is

> changed in a manner that affects equals comparisons

> while the object is an element in the set. A special

> case of this prohibition is that it is not

> permissible for a set to contain itself as an

> element.

>

you can see that was where he was coming from because you yourself, just like him, did not and still do not correctly comprehend what the doc is saying - it is a sad thing that the doc is so written that it oftentimes mislead people, and the 'commom people' oftentimes cannot read critically.

> So, both people are right.

only one is correct.

> One is allowed to use

> mutable objects in a Set, though Set will no longer

> be able to guarantee uniqueness of mutable elements.

> In effect, the contract no longer applies and the

> e behavior is not specified. My bottom line take on

> that: you can use mutable objects, just be more

> careful than normal.

besides an english error: 'takes' shopuld be in place of 'take' as the subject is bottom line which is third person singular in present tense, the major point of what the dos is saying is NOT that you can not override the equals() inherited from the object class on mutable objects, rather it is saying you almost always have to override it so that the set can return a meaningful comparison result.

and when overriding it using a value comparison, you need to do the comparison on a stable attribute value as an id value on the object. oftentimes you need to override the hashcode() as well. look back on my previous posts on this.

read critically.

Saisha at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 51
> A special> case of this prohibition is that it is not> permissible for a set to contain itself as an> element.> for this we actually went thru a case maybe a couple of years ago?
Saisha at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 52

> I will, regretfully, have to concede DaFei's point

> here. If the same logic for immutability was

> followed (in terms of breaking the contract of Set),

> then I could never place java.util.Date in a

> Collection either. I can easily mutate its value via

> setTime().

You are not using the same logic. You have extrapolated part of a discussion about whether or not StringBuffer should override equals() to compare contents and turned it into some sort of Java axiom. That's not how I intended it, the context is completely different and it's been twisted. It also does not address the other points.

Who is "both"? Was daFei right when he said it was "hard" to compare StringBuffer's contents or when he said it didn't do anything useful?

kablaira at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 53

> > I will, regretfully, have to concede DaFei's point

> > here. If the same logic for immutability was

> > followed (in terms of breaking the contract of

> Set),

> > then I could never place java.util.Date in a

> > Collection either. I can easily mutate its value

> via

> > setTime().

> >

> your english would have been perfect had you used the

> word 'gladly' instead of 'regretfully', unless of

> course you are admitting with regret that you did not

> following my teachings.

>

> > However, I can easily see where Kablair is coming

> > from. Quoted from the API docs for Set:

> >

> > Note: Great care must be exercised if mutable

> > objects are used as set elements. The behavior of

> a

> > set is not specified if the value of an object is

> > changed in a manner that affects equals

> comparisons

> > while the object is an element in the set. A

> special

> > case of this prohibition is that it is not

> > permissible for a set to contain itself as an

> > element.

> >

> you can see that was where he was coming from because

> you yourself, just like him, did not and still do not

> correctly comprehend what the doc is saying - it is a

> sad thing that the doc is so written that it

> oftentimes mislead people, and the 'commom people'

> oftentimes cannot read critically.

>

> > So, both people are right.

>

> only one is correct.

>

> > One is allowed to use

> > mutable objects in a Set, though Set will no

> longer

> > be able to guarantee uniqueness of mutable

> elements.

> > In effect, the contract no longer applies and the

> > e behavior is not specified. My bottom line take

> on

> > that: you can use mutable objects, just be more

> > careful than normal.

>

> besides an english error: 'takes' shopuld be in place

> of 'take' as the subject is bottom line which is

> third person singular in present tense, the major

> point of what the dos is saying is NOT that you can

> not override the equals() inherited from the object

> class on mutable objects, rather it is saying you

> almost always have to override it so that the set can

> return a meaningful comparison result.

>

> and when overriding it using a value comparison, you

> need to do the comparison on a stable attribute value

> as an id value on the object. oftentimes you need to

> override the hashcode() as well. look back on my

> previous posts on this.

>

> read critically.

1. You have not addressed a single point made.

2. The only two points you have made yourself have been shown to be completely inaccurate.

kablaira at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 54

your english would have been perfect had you used the word 'gladly' instead of 'regretfully', unless of course you are admitting with regret that you did not following my teachings.

The adverb chosen is the one I still deem most fitting. English should be capitalized in your reply. (You really want to take me on via grammar? Losing proposition.)

you can see that was where he was coming from because you yourself, just like him, did not and still do not correctly comprehend what the doc is saying - it is a sad thing that the doc is so written that it oftentimes mislead people, and the 'commom people' oftentimes cannot read critically.

Re-read my previous reply. If you stll do not understand it, continue pursuing your study of English.

besides an english error: 'takes' shopuld be in place of 'take' as the subject is bottom line which is third person singular in present tense,

No, the idiom uses the word 'take'. My final take. Take here is a noun, so considerations of what person I am using do not apply. While the noun 'take' could be made plural, it would not be normal usage,

the major point of what the dos is saying is NOT that you can not override the equals() inherited from the object class on mutable objects, rather it is saying you almost always have to override it so that the set can return a meaningful comparison result.

Yes, I too can read the API docs. And as I already stated, I agree with your understanding of equals() and Set, at least the last few posts.

and when overriding it using a value comparison, you need to do the comparison on a stable attribute value as an id value on the object. oftentimes you need to override the hashcode() as well. look back on my previous posts on this.

Are you actually taking pride in the fact that you understand what is at best a rudimentary topic? Any student would know that much (and probably more) after the second day covering the Collections API.

- Saish

Saisha at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 55

You are not using the same logic. You have extrapolated part of a discussion about whether or not StringBuffer should override equals() to compare contents and turned it into some sort of Java axiom. That's not how I intended it, the context is completely different and it's been twisted. It also does not address the other points.

Who is "both"? Was daFei right when he said it was "hard" to compare StringBuffer's contents or when he said it didn't do anything useful?

Definitely fair points. If I went off on a tangent, my apologies.

- Saish

Saisha at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 56

>

> You are not using the same logic. You have

> extrapolated part of a discussion about whether or

> not StringBuffer should override equals() to compare

> contents and turned it into some sort of Java axiom.

> That's not how I intended it, the context is

> completely different and it's been twisted. It also

> does not address the other points.

>

> Who is "both"? Was daFei right when he said it was

> "hard" to compare StringBuffer's contents or when he

> said it didn't do anything useful?

>

>

> Definitely fair points. If I went off on a tangent,

> my apologies.

>

> - Saish

Considering you're not the only one who thought I was saying that I must have phrased it poorly. It doesn't help that my original points have been somewhat blurred because of completely seperate counter-points that were made to illustrate the inaccuracy of what daFei said.

Regardless, the mutability of StringBuffer is as much an issue in whether or not equals() and hashCode() should be overridden as it is with any other object. Within the context of StringBuffer it is important for understanding why (in so far as I proposed) something that is appropriate with String becomes inappropriate in StringBuffer.

kablaira at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 57

Regardless, the mutability of StringBuffer is as much an issue in whether or not equals() and hashCode() should be overridden as it is with any other object. Within the context of StringBuffer it is important for understanding why (in so far as I proposed) something that is appropriate with String becomes inappropriate in StringBuffer.

I completely agree. Placing a StringBuffer within a Collection makes as much sense to me as placing an I/O stream in one. Sorry, let me be a bit more specific. The above and trying to access a given StringBuffer or I/O stream via a get() depending an overridden version of equals() would be inappropriate. Possible, but to a certain degree also non-sensical.

- Saish

Saisha at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 58

> I will, regretfully, have to concede DaFei's point

> here.

Good grief man, what are you doing? Arguing wih daFei is bad enough, encouraging him is just crazy.

> If the same logic for immutability was

> followed (in terms of breaking the contract of Set),

> then I could never place java.util.Date in a

> Collection either. I can easily mutate its value via

> setTime().

Date is possibly the worst API in the JDK. I wouldn't use it as an exampl for anything. In any event, the whole point of a StringBuffer is that it's only real purpose is fo modification. I've never had a StringBuffer that I kept around without anything attemping to modify it. One the other hand, who the hell puts a StringBuffer in a Set or uses it as a key in a Map.

Final point: this is yet another issue that would be solved by having an Equalato interface in the Collections framework. You people arguing here should be voting for it.

dubwaia at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 59

> > I will, regretfully, have to concede DaFei's point

> > here.

>

> Good grief man, what are you doing? Arguing wih

> daFei is bad enough, encouraging him is just crazy.

>

any other attempt would be wrong.

> > If the same logic for immutability was

> > followed (in terms of breaking the contract of Set),

> > then I could never place java.util.Date in a

> > Collection either. I can easily mutate its value via

> > setTime().

>

it is not that you cannot put date in a set, it wont break, in terms of crashing, the code, just that once the value based on which is your equals() changes, the set will yeld a different result. nothing is wrong, you should exspect it to be so; otherwise you should implement your equals() based on some stable values.

> Date is possibly the worst API in the JDK. I

> wouldn't use it as an exampl for anything.

some methods are deprecated in date for some reasons other than what you think to be the worst.

> In any

> event, the whole point of a StringBuffer is that it's

> only real purpose is fo modification.

correct, as indicated by the name, its a buffer.

> I've never had

> a StringBuffer that I kept around without anything

> attemping to modify it. One the other hand, who the

> hell puts a StringBuffer in a Set or uses it as a key

> in a Map.

>

that however should not be a reason that you can not put it there.

> Final point: this is yet another issue that would be

> solved by having an Equalato interface in the

> Collections framework. You people arguing here

> should be voting for it.

no, it wont. bad suggesstion obviously. i for one wont vote for it.

dubwaia at 2007-7-20 19:41:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 60

> > Final point: this is yet another issue that would

> be

> > solved by having an Equalato interface in the

> > Collections framework. You people arguing here

> > should be voting for it.

>

> no, it wont. bad suggesstion obviously. i for one

> wont vote for it.

Why won't it? I'm sure this will be interesting.

dubwaia at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 61

> > > Final point: this is yet another issue that

> would

> > be

> > > solved by having an Equalato interface in the

> > > Collections framework. You people arguing here

> > > should be voting for it.

> >

> > no, it wont. bad suggesstion obviously. i for one

> > wont vote for it.

>

> Why won't it? I'm sure this will be interesting.

not sure what you mean. the object has this equals already, so virtually all objs have it. why would you want an additional one in the collections? you cannot specify implementations, which would be situational, depending on the needs under certain situaltion.

dubwaia at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 62

> > I will, regretfully, have to concede DaFei's point

> > here.

>

> Good grief man, what are you doing? Arguing wih

> daFei is bad enough, encouraging him is just crazy.

>

I did have regret. :^)

> > If the same logic for immutability was

> > followed (in terms of breaking the contract of

> Set),

> > then I could never place java.util.Date in a

> > Collection either. I can easily mutate its value

> via

> > setTime().

>

> Date is possibly the worst API in the JDK. I

> wouldn't use it as an exampl for anything. In any

> event, the whole point of a StringBuffer is that it's

> only real purpose is fo modification. I've never had

> a StringBuffer that I kept around without anything

> attemping to modify it. One the other hand, who the

> hell puts a StringBuffer in a Set or uses it as a key

> in a Map.

>

Agreed. And they did not make things all that much better with Calendar, having its own, different quirks. I myself have never stored anything like a StringBuffer or I/O stream in a collection that I expected to subsequently retrieve successfully via an implicit equals() call. StringBuffer has its uses, and Strings has its own.

> Final point: this is yet another issue that would be

> solved by having an Equalato interface in the

> Collections framework. You people arguing here

> should be voting for it.

I'm not sure about the name itself, Equalato. But I do like the idea. :^)

- Saish

Saisha at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 63
no, it wont. bad suggesstion obviously. i for one wont vote for it.<sigh>Some people just want attention. Even if it is bad attention.</sigh>- Saish
Saisha at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 64

> I will, regretfully, have to concede DaFei's point

> here. If the same logic for immutability was

> followed (in terms of breaking the contract of Set),

> then I could never place java.util.Date in a

> Collection either. I can easily mutate its value via

> setTime().

I can modified any instance of a class including String.

Doesn't stop me from using them in hashes though.

I don't see how kablair's code changes that however. The very nature of a StringBuffer is that it is mutable. So if you concerned about mutablity in a hash it doesn't matter how it implements equals or hashcode because the class itself is suspect.

jschella at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 65
> Date is possibly the worst API in the JDK. My vote goes for the decision to use static initializers to register JDBC drivers.
jschella at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 66

>

> > > If the same logic for immutability was

> > > followed (in terms of breaking the contract of Set),

> > > then I could never place java.util.Date in a

> > > Collection either. I can easily mutate its value via

> > > setTime().

> >

>

> it is not that you cannot put date in a set, it wont

> break, in terms of crashing, the code, just that

> once the value based on which is your equals()

> changes, the set will yeld a different result.

> nothing is wrong, you should exspect it to be so;

> otherwise you should implement your equals() based on

> some stable values.

I see - so you are suggesting that Date.equals() shouldn't actually compare the date values because they might change.

jschella at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 67
I can modified any instance of a class including String.AccessibleObject.setAccessible(true) per chance? :^)- Saish
Saisha at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 68

> I see - so you are suggesting that Date.equals()

> shouldn't actually compare the date values because

> they might change.

the purpose of equals is actually not for general comparisons, a major part of the reasons behind it is for identifications, meaning sir kblair's original post was not totally wrong. it is easy to implement value equals on immutable objects, but it is very hard to do it on other objects. equals based on ever changing values oftentimes are confusing, and may lead to errors.

Saisha at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 69

> not sure what you mean. the object has this equals

> already, so virtually all objs have it. why would you

> want an additional one in the collections? you cannot

> specify implementations, which would be situational,

> depending on the needs under certain situaltion.

I guess you never used a Comparator.

dubwaia at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 70
> I guess you never used a Comparator.and exactly this is where yu are confused. comparator uses the compare(), the equals() is not for that purpose. the equals() is more for object identifications.
dubwaia at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 71

> and exactly this is where yu are confused.

>

> comparator uses the compare(), the equals() is not

> for that purpose. the equals() is more for object

> identifications.

No this where you are confused. Equals says whether Objects are equivalent. == is for identification.

dubwaia at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 72

> > and exactly this is where yu are confused.

> >

> > comparator uses the compare(), the equals() is not

> > for that purpose. the equals() is more for object

> > identifications.

>

> No this where you are confused. Equals says whether

> Objects are equivalent. == is for identification.

abstractly.

dubwaia at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 73

> > I see - so you are suggesting that Date.equals()

> > shouldn't actually compare the date values because

> > they might change.

>

> the purpose of equals is actually not for general

> comparisons, a major part of the reasons behind it is

> for identifications, meaning sir kblair's original

> post was not totally wrong. it is easy to implement

> value equals on immutable objects, but it is very

> hard to do it on other objects. equals based on ever

> changing values oftentimes are confusing, and may

> lead to errors.

When used in conjunction with things like collections, yes. Implementing the code is usually trivial, it's the implications that are of concern.

kablaira at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 74

> > > and exactly this is where yu are confused.

> > >

> > > comparator uses the compare(), the equals() is

> not

> > > for that purpose. the equals() is more for

> object

> > > identifications.

> >

> > No this where you are confused. Equals says

> whether

> > Objects are equivalent. == is for identification.

>

> abstractly.

I think you mean 'exactly'

The point is that whether two objects are equivalent depends on the context. For example, when are two CharSequences equivalent? Can you use equals to determine this? Given a class Point and another that extends it called ColorPoint, when are two points equal? Can you use equals to determine whether two points (one or both may be ColorPoints) are equivelant in a reliable and useful way?

dubwaia at 2007-7-20 19:41:57 > top of Java-index,Other Topics,Patterns & OO Design...
# 75

> collections, yes. Implementing the code is usually

> trivial, it's the implications that are of concern.

shouldnt it be because of the implications, the implementations are therefore not trivial?

as i now understand your way of logic, i see where you came from: very impressive:)

at 2007-7-20 19:42:02 > top of Java-index,Other Topics,Patterns & OO Design...
# 76

> shouldnt it be because of the implications, the

> implementations are therefore not trivial?

>

> as i now understand your way of logic, i see where

> you came from: very impressive:)

I suppose you could look at it that way. I'm not sure I agree with it though. It's very easy to write the code to do it and have it work. You can even document it clearly and have an expert not have issues. The average person isn't necessarily going to know the details of how other classes use equals(), directly or indirectly, and what they expect from it. They'll go try and use it with something like a Set and suddenly have weird behavior.

Frankly, I think 80% of my time is spent trying to decide what an object should do. It takes very little time to write the actual code once I've decided. That's my issue with StringBuffer.equals(). It's easy to do, but it shouldn't be done.

kablaira at 2007-7-20 19:42:02 > top of Java-index,Other Topics,Patterns & OO Design...
# 77

> Frankly, I think 80% of my time is spent trying to

> decide what an object should do. It takes

> very little time to write the actual code once I've

> decided. That's my issue with StringBuffer.equals().

> It's easy to do, but it shouldn't be done.

i feel the same way. java/oop is mostly design work, coding is not a big deal.

as for wheather or not your objects should have an equals() other than the original one depends on the need. hibernate for example requires you provide a special equals() (together with the hash()), it recommends base it on the index value, which makes lots of sense as the index id on a database table stays forever with a set of records, doing it this way is very much like implenting it on an immutable object.

kablaira at 2007-7-20 19:42:02 > top of Java-index,Other Topics,Patterns & OO Design...