Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

== vs. equals() doubt  RSS feed

 
Bhanuprasad saketi
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello
i am try to write scjp exam but i have one doubt in == and equals()
any one please tell me
 
Bhanuprasad saketi
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
class Test
{
public static void main(String ...args)
{
Integer i1=100;
Integer i2=100;
Integer i3=1000;
Integer i4=1000;
if(i1==i2)
{
System.out.println("i1 and i2 are equals");
}
else
{
System.out.println("i1 and i2 are not equals");
}
if(i3==i4)
{
System.out.println("i3 and i4 are equals");
}else
{
System.out.println("i3 and i4 are not equals");
}
}
}
output:i1 and i2 are equals
i3 and i4 not equals


what is the reason above the output

any one please tell me......
 
fred rosenberger
lowercase baba
Bartender
Posts: 12542
48
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I forget how many, but some Integer objects are cached...so anything below (let's say) 256 is pre-built, and thus all references point to the same object. So, clearly, 100 is below that threshold, and 1000 is over it.

The difference between == and .equals is sort of like comparing bank accounts. I may have two pieces of paper, each having a bank account number written on it.

== will tell you if the bank account numbers are the same.

.equals will tell you if the two accounts have the same amount of money in them.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bhanuprasad saketi wrote:i am try to write scjp exam but i have one doubt in == and equals()

Believe me, the SCJP exam is the only possible reason for having doubts about == and equals().

After you've passed it, if you're smart, you will never, ever, ever, EVER use '==' for anything except comparing primitives.

Winston
 
shaileshkumar mistry
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

HI

till Integer 127.. Integer objects are cached. so if your Integer object hold the value less than 127 the value will be true if you try to do "==" operation two integer object having same value below 127.

and if two Integer object contains the value more than 127 and if you try to do "==" it will be false
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:After you've passed it, if you're smart, you will never, ever, ever, EVER use '==' for anything except comparing primitives.

Or enums.

Or you'll move on to any of the other JVM languages like Scala or Groovy that remove these odious rules and let you use == to mean what most people expect it to mean, rather than one Java defines it to mean.
 
R. Jain
Ranch Hand
Posts: 375
1
Java Python Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
fred rosenberger wrote:I forget how many, but some Integer objects are cached...so anything below (let's say) 256 is pre-built, and thus all references point to the same object. So, clearly, 100 is below that threshold, and 1000 is over it.

The difference between == and .equals is sort of like comparing bank accounts. I may have two pieces of paper, each having a bank account number written on it.

== will tell you if the bank account numbers are the same.

.equals will tell you if the two accounts have the same amount of money in them.


Just giving the exact data: -

The range for which it happens is :-
(-128 to 127)... Outside this range any integer with same values will be different...
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16028
87
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your question is a frequently asked question; have a look at some previous discussions, which you can find with a search.

AutoBoxing, ==, != & equals
discrepancy in comparison (==)
Query: In boxing why == & != both works
'==' operators with Wrapper class
how == works on Integer wrapper class
Wrapper Class '=='
 
Stuart A. Burkett
Ranch Hand
Posts: 679
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
R. Jain wrote:The range for which it happens is :-
(-128 to 127)... Outside this range any integer with same values will be different...

Unless you've configured your system to have a higher upper range limit which is possible.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike Simmons wrote:Or enums.

True; although I suspect that one could be accused of micro-optimization if you do.
1. All it saves is a call to Object.equals().
2. I suspect that the latest compilers are smart enough to work it out for themselves; and if they aren't, they should be.

Or you'll move on to any of the other JVM languages like Scala or Groovy that remove these odious rules and let you use == to mean what most people expect it to mean, rather than one Java defines it to mean.

While I'm certainly not against anyone learning new languages, it seems to me that it's the SCJP and all these darn wrapper caches that are the cause of confusion for beginners in Java; and I'd categorize that as "API leak", not a problem with the language itself.

To me the rules are absolutely straightforward:
1. You use '==' for primitives ONLY.
2. You use equals() for everything else.
3. You create Strings and wrapper objects with valueOf(), rather than constructors, unless you specifically need a clone - and why one would need a clone of an immutable object I simply can't imagine.
Everything else is API leak; unfortunately now public domain.

Personally, I'd also make it a compiler warning if '==' is used for anything except specifically comparing primitives.

My 2 cents.

Winston
 
Campbell Ritchie
Marshal
Posts: 55698
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote: . . . After you've passed it, if you're smart, you will never, ever, ever, EVER use '==' for anything except comparing primitives. . . .
And enum constants.

And welcome to the Ranch
 
Campbell Ritchie
Marshal
Posts: 55698
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
fred rosenberger wrote:I forget how many, . . .
You are right to forget, Fred.

What you should do is always use Integer#valueOf(123), not new Integer(123), and that will take care of the caching for you.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:And enum constants.

See above. 'Morning Campbell.

Winston
 
Campbell Ritchie
Marshal
Posts: 55698
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
shaileshkumar mistry wrote:
HI

till Integer 127.. Integer objects are cached.. . . .
And was mistaken.
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:Personally, I'd also make it a compiler warning if '==' is used for anything except specifically comparing primitives.


I'm not convinced it's that simple. Let's say you've got two reference variables. You want to check if they refer to the same object. Oh yes, and either or both of them might be null. Try doing that without using ==.
 
Campbell Ritchie
Marshal
Posts: 55698
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
R. Jain wrote: . . . (-128 to 127)... Outside this range any integer with same values will be different...
And that is mistaken.

So many people read -128…127 and think that is the range. It isn’t. You need to read the Java Language Specification and Integer#valueOf(int) documentation carefully, where you find it is -128…127 and maybe more. It is in fact undefined, -128…127 being only a minimum. As Stuart Burkett said, you can alter that. So the behaviour of this code can legitimately vary from machine to machine, or even on the same machine from run to run if the JVM is configured differently:-It might be because when Java was developed, 8MB was a generous amount of memory in a computer, whereas nowadays computers are available with > 1000× as much memory.

To make things even more interesting, the behaviour of Integer.valueOf("123") may be different again.

Winston is right, not only that I ought to read the whole thread before going on about enums (morning, Winston), but also that you should avoid == like the plague.

There are other languages where == is overloaded; I met one chap on our MSc course who used == in Java after coming from a C# background. His program ran, because all the String instances were interned. He serialised some objects and de‑serialised them, and now some of the Strings were no longer the interned objects, and all sorts of errors started to occur. In C# == is overlaoded “to mean what most people expect it to mean,” as Mike S said.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Matthew Brown wrote:
Winston Gutkowski wrote:Personally, I'd also make it a compiler warning if '==' is used for anything except specifically comparing primitives.

I'm not convinced it's that simple. Let's say you've got two reference variables. You want to check if they refer to the same object. Oh yes, and either or both of them might be null. Try doing that without using ==.

Hmmm. OK, I'll concede the point about null; but it does seem to me that people obsess unnecessarily about the need for checking whether two objects are the same.

When would you need to do this? A properly written equals() method should have this as it's first check; and if it's imperative that your particular class be able to determine if another instance is identical, then add a sameObjectAs(Object) method to the API.

Other than that, there's always the SuppressWarnings annotation.

Winston
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Trying to call equals() when both object might be null is a main reason I often prefer == when it's guaranteed to do what I want (i.e. primitives, enums, Class instances, occasionally other classes if they're defined to have canonic instances). This frequent problem has finally been addressed by Objects.equals(), but why did such a basic operation need to wait for Java 7? One of my many frustrations with Java. Oh well.

Oh, and I also dislike the tedious verbosity of .equals() when == looks so much cleaner. It's just too bad that Java defined things the way they did; most all the successor languages that I know of fix this.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Winston Gutkowski wrote: . . . After you've passed it, if you're smart, you will never, ever, ever, EVER use '==' for anything except comparing primitives. . . .
And enum constants.

Not just the constants - it also works for any variable referencing an enum type (or null). This is one of the main reasons I would use it.
 
R. Jain
Ranch Hand
Posts: 375
1
Java Python Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
R. Jain wrote: . . . (-128 to 127)... Outside this range any integer with same values will be different...
And that is mistaken.

So many people read -128…127 and think that is the range. It isn’t. You need to read the Java Language Specification and Integer#valueOf(int) documentation carefully, where you find it is -128…127 and maybe more. It is in fact undefined, -128…127 being only a minimum. As Stuart Burkett said, you can alter that. So the behaviour of this code can legitimately vary from machine to machine, or even on the same machine from run to run if the JVM is configured differently:-It might be because when Java was developed, 8MB was a generous amount of memory in a computer, whereas nowadays computers are available with > 1000× as much memory.



Oh... that thing is something new I know now....

Thanks Campbell & Stuart...
 
Stevens Miller
Bartender
Posts: 1444
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just to chime in: with the addition of "<object> == null," I agree with Winston's list. I note that NetBeans even catches <object>.equals(null) (which is either false or throws a NullPointerException, but is never true) and will change it to <object> == null for you.

I'll add that I often write code that looks to see if an object is null, mostly as a way to maintain state about whether certain data structures are in memory at any given time or not. If that's a bad practice, I'm open to alternatives.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I like the idea of a compiler warning - but frankly for such a tool, it should be trivial to add null, enums, and Class types as well, which will all work perfectly well. And then all the actual error cases would be caught, while legitimate uses would be allowed. And overly simplistic, dogmatic rules can be simply ignored.
 
Stevens Miller
Bartender
Posts: 1444
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I suspect that feelings about what == should do when applied to objects follow a familiar truth table:



Reading the Javadoc on Object.equals reveals that it embeds a rather non-obvious requirement on anything you might do to override it (without which, it ends up almost the same as what == does already): "Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes."

This kind of thing puts me off of standard-library types of calls to compare objects entirely. I tend to write my own comparators that are, if I want them to be, only dependent on certain aspects of an object to measure its equality to another object, and I definitely don't want to find out that I violated some "contract" made by a method I never heard of, don't need, and won't use.

While having == do what .equals() does might be preferable, you'd still need some way to test if two references were truly to the same object. Rare, perhaps, but I don't want to lose it. Java rather blessedly (imho) does not allow operator overrides. Whenever I encounter one of those in C++, it is a throw-something-at-the-wall moment for me. I expect to have to look at source code or some doc for a method call; I do not expect to have to inquire as to whether or not "==" is really ==, or is it some gawdawful horror one of my oh-so-clever colleagues came up with (typically on the same day they learned you could override operators). Since Object.equals needs to be overridden to do anything really useful, seems that you'd also have to override == in the same cases. I believe I would lose years of my remaining time if I had to deal with how people would (ab)use that. There's no way to make everyone happy, but I will say that at least I am happy with things as they are. If it's I-am-happy-and-someone-else-is-not, or someone-else-is-happy-and-I-am-not, I'll take the former, please.

As for overly simplistic, dogmatic rules, I'll just say that, if it we only had more of those, there'd be more decent code in the world, and a lot less vermicelli.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:[standard equals/hashCode contract stuff removed]

This kind of thing puts me off of standard-library types of calls to compare objects entirely. I tend to write my own comparators that are, if I want them to be, only dependent on certain aspects of an object to measure its equality to another object, and I definitely don't want to find out that I violated some "contract" made by a method I never heard of, don't need, and won't use.

Well, umm, that's a pretty important pair of methods to know about in Java. Do you never use HashMap or HashSet? One can argue that it should have been designed differently (I would have it throw UnsupportedOperationException by default, so you'd be promptly notified if you ever put something in a hash table without a proper equals() and hashCode()). But regardless, I would suggest that the equals() / hashCode() contract is important to know about in Java as it is, and it is documented right there in the API for those methods.

Stevens Miller wrote:While having == do what .equals() does might be preferable, you'd still need some way to test if two references were truly to the same object. Rare, perhaps, but I don't want to lose it. Java rather blessedly (imho) does not allow operator overrides.

Well, we're not talking about an override; we're talking about a language-level change in how == works. Which will never happen, but it's irritating. Languages like Scala, Groovy, and JRuby simply define == to do the most commonly-desired operation, compare object contents, and then define other operators ('foo === bar' in Groovy; 'foo eq bar' in Scala, foo.object_id == bar.object_id in Ruby) for the less-commonly-desired operation, comparing object identity. Certainly this operation needs to be possible. But it can afford to have a seldom-remembered operator; leave == to the most useful operation.
 
Stephan van Hulst
Saloon Keeper
Posts: 7806
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think == should be object equality, and there could be some Objects.areIdentical(Object o1, Object... objects) method for identity. And I've always enjoyed operator overloading. Not sure what makes them different than other methods.

I also would have liked Hashable and HashFunction interfaces (analogous to Comparable and Comparator) which declare hash() and isEqual(T), and hash(T) and areEqual(T, T) methods respectively. I've found that sometimes I want to store objects in a HashMap/HashSet using different criteria than the default equals() and hashCode() methods.
 
Stevens Miller
Bartender
Posts: 1444
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike Simmons wrote:
Stevens Miller wrote:[standard equals/hashCode contract stuff removed]

This kind of thing puts me off of standard-library types of calls to compare objects entirely. I tend to write my own comparators that are, if I want them to be, only dependent on certain aspects of an object to measure its equality to another object, and I definitely don't want to find out that I violated some "contract" made by a method I never heard of, don't need, and won't use.

Well, umm, that's a pretty important pair of methods to know about in Java.


Quite true, and that's what bothers me. I can't think of very many methods that must be overridden in pairs, or not at all.

Do you never use HashMap or HashSet?


Nope. Not yet, anyway.


Stevens Miller wrote:While having == do what .equals() does might be preferable, you'd still need some way to test if two references were truly to the same object. Rare, perhaps, but I don't want to lose it. Java rather blessedly (imho) does not allow operator overrides.

Well, we're not talking about an override; we're talking about a language-level change in how == works.


I think we are talking about an override, if you want equals to be replaced by ==, as equals is clearly written to be overridden. If you couldn't override ==, you'd still need equals for some cases.

Which will never happen, but it's irritating. Languages like Scala, Groovy, and JRuby simply define == to do the most commonly-desired operation, compare object contents, and then define other operators ('foo === bar' in Groovy; 'foo eq bar' in Scala, foo.object_id == bar.object_id in Ruby) for the less-commonly-desired operation, comparing object identity. Certainly this operation needs to be possible. But it can afford to have a seldom-remembered operator; leave == to the most useful operation.


I'd meet you half-way on that, if, say, Java were to add a new operator that did what you are proposing for ==. That way, you don't have the risk of a NullPointerException like you do with equals, but you don't change the current usage (and all code presently reliant thereupon) of ==. (Not sure what it could be, maybe "<=>" or something...)

As language deficiencies go, I'd rank this whole issue a lot lower in priority for changes than, say, the lack of unsigned integer primitive data types. But that's a topic for another thread, I suppose.
 
Stevens Miller
Bartender
Posts: 1444
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:I've always enjoyed operator overloading. Not sure what makes them different than other methods.


It's probably a reflection of my own experience, more than a position I can defend objectively. I've spent a lot of my life reading code. In C, you always expect to need to go look up what a routine does, while you know you never need to look up what an operator does. In C++, you have to look them all up, which I find I often forget to do for operators, which leads me into making bad assumptions, and that just makes me cranky later, when I realize I was hoodwinked by an overridden operator that wasn't doing what I thought it was doing. Also, to be quite judgmental and blunt about it, most of the overrides I've seen applied to operators have been really badly implemented (but that, of course, is just my opinion).
 
Stephan van Hulst
Saloon Keeper
Posts: 7806
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My point is mostly that people use operator overloading/overriding wrongly. Doesn't make it a bad feature, it makes the implementations that people write bad. People misuse inheritance a lot, but that doesn't make inheritance inherently bad.

I would enjoy using < and > instead of compareTo() < 0 and compareTo() > 0, or + and - to add or subtract periods of time from points in time or other periods of time, etc. It would also be nice to overload the ^ operator to perform the power function on numbers.
 
Stephan van Hulst
Saloon Keeper
Posts: 7806
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:I'd rank this whole issue a lot lower in priority for changes than, say, the lack of unsigned integer primitive data types. But that's a topic for another thread, I suppose.


At the risk of hijacking this topic (not sure we haven't already, maybe we should split this discussion off), I really think it was a great choice to dump unsigned integer values. They're only used in low level applications, and Java was written with a high abstraction level in mind. High level code really shouldn't care about the internal organization of primitives. On top of that, it's really trivial to convert signed integers to unsigned equivalents and vice versa.
 
Stevens Miller
Bartender
Posts: 1444
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:
Stevens Miller wrote:I'd rank this whole issue a lot lower in priority for changes than, say, the lack of unsigned integer primitive data types. But that's a topic for another thread, I suppose.


At the risk of hijacking this topic (not sure we haven't already, maybe we should split this discussion off), I really think it was a great choice to dump unsigned integer values. They're only used in low level applications, and Java was written with a high abstraction level in mind. High level code really shouldn't care about the internal organization of primitives. On top of that, it's really trivial to convert signed integers to unsigned equivalents and vice versa.


Yeah, that's the standard dodge. Not much help for me. I do image-processing work on real-time video. I don't have time to convert a raster full of unsigned bytes to signed ints, process them, and convert them back again. I don't know if you'd call what I do "low level," but it does force me to use the JNI and C++ for a lot of things. (I'm no network guy, but I hear that network programmers are really annoyed with the lack of unsigned bytes in Java, too.)

I read an article about this that cited to an interview with one of the early Java designers. His rationale, he said, was that "people didn't really understand unsigned types."

I would beg to differ with him.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike Simmons wrote:One can argue that it should have been designed differently (I would have it throw UnsupportedOperationException by default, so you'd be promptly notified if you ever put something in a hash table without a proper equals() and hashCode()).

YES. Oh yesss. I've always thought the same; particularly when you already have System.identityHashCode(). I reckon that one change would've saved, what...a few billion pages of literature? Certainly a decent size forest's worth.

I have to admit to agreeing with Stephan's (and, I suspect, Matthew's) contention that this is one instance when operator overloading might have helped. I generally agree that Java's decision not to use it in general is a good one, but there's already one exception ('+'); why not two?
If it had been defined at the language level, you wouldn't need to trawl about for implementations: for reference types '==' == equals(); and you use a different operator (':=', '===' or a 'sameAs' keyword?) for comparing reference identities - end of story.

However, I suspect it's all far too late and we're all barking at the moon.

Winston
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:My point is mostly that people use operator overloading/overriding wrongly. Doesn't make it a bad feature, it makes the implementations that people write bad. People misuse inheritance a lot, but that doesn't make inheritance inherently bad.


I can see both points of the operator overloading argument. When used well it makes code very intuitive. But you can really mess with people's minds. I think there's something more fundamental about an operator compared to a method, and if it behaves in a way you don't expect it's even more confusing.

I suppose the bottom line is: I wish I could use operator overloading, but I'm glad other people can't .

Having recently been learning Scala, the proliferation of new operators there (since it makes - almost - no distinction between between methods and operators) is one thing about it that I find really confusing.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Matthew Brown wrote:I suppose the bottom line is: I wish I could use operator overloading, but I'm glad other people can't .

Well, except me that is.

And, as you quite rightly pointed out, you still have the business of '== null'; so: an exception to an exception? Fine by me; but I suspect the purists would be chuntering.

Winston
 
Stevens Miller
Bartender
Posts: 1444
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Matthew Brown wrote:I suppose the bottom line is: I wish I could use operator overloading, but I'm glad other people can't .

Well, except me that is.


Ah. I believe you boys have figured it out.
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bhanuprasad saketi,
Your post was moved to a new topic.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!