if (!"success".equals(statusCheck))
Answer from 勿绮语 on Stack Overflowequals() is a byproduct of an attempt to improve C++ when it was created. C++ has operator overloading which allows you to perform custom operations when called with otherwise valid operators such as <, >, !=, ==, and even =.
The team made the decision (wisely so) to make equality be class method rather than having external static methods as it was done in C++. However, this also meant that equals() coupled with hashCode() defined how such classes were handled in collection classes.
Since any class could in theory override equals() or hashCode(), it means that just because you have a collection of a certain type does not guarantee that behavior is uniform.
For instance, suppose class A has two members x and y used to determine equality. Along comes class B which has x, y, and z. If an instance of B had the same values x and y, how would you go about inserting this instance in a Set? If you call the equals of an instance of A, it will determine the two to be equal and if you call the equals of an instance of B, it will return false since it is not an instance of B.
To be perfectly correct, class B would have to treat member z as an additional condition only in the case in which it is an instance of B, otherwise it lends itself to the equals() method of class A, and, if such a thing is not possible, class B should not allow itself to override equals() or hashCode(). This creates a sticky situation since in theory you should not concern yourself with how the parent class works from an implementation standpoint (if done right anyway), but yet here we are.
You could make class A final to prevent such things from happening, but then of course you can never extend class A. Java makes a point of making certain standard classes like String final to prevent complications of this nature (very smart decision on their part). I think at the end of the day, what matters is that you are very careful in your usage of equals() and hashCode(). I try to use it sparingly, and I am always mindful of which classes I mean to be available in a library and which classes are for internal use as to not to create conditions where things could go horribly wrong.
The Liskov substitution principle is fine in theory, but in practice you can never quite manage it. Take Collection as an example. Collection is implemented by ArrayList, Set, or LinkedList among others. While it is true that you could achieve the same ultimate goal by replacing a Collection with say a HashSet, it is not an ideal implementation for performing operations on all objects contained within (better LinkedHashSet at that point). It wouldn't break existing code, but you may potentially render it grossly inefficient depending on how that Collection is used. Consider that this is a rather clean example too.
If you're lucky, only the implementation details change, but many behave radically different, with some methods throwing a NotImplementedException.
Thus requiring that classes implementing equals() must respect the Liskov substitution principle is asking a lot, and I suspect that they didn't want to alienate the majority of C++ programmers getting familiar with Java.
Simple argument against your logic is, what is the use of the equals method if it's modified to be a final. Then it would execute same logic against any given objects. If you want to compare A and AX in the object class what would be the logic?
Overriding of final method is allowed to be able to verify if two different objects (living in 2 different memory locations) are actually equals (== method is there to check if two references are of the same object) based on defined logic. For example if you have a user object like this,
User
{
string name;
string email;
string phone;
}
For one system, it would be the email you might interest to uniquely identifying a user. So you may compare based on email value. But some other system might use phone as the unique identifier. So they may decide to implement different equals methods.
When it comes to logic of A,AX and Liksov substitution principle which is,
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
So if you do,
AX ax1 = new AX();
AX ax2 = new AX();
ax1.equals(ax2);
and
A a = new AX();
AX ax = new AX();
a.equals(ax);
should give you the same output, and it will.
Check out this article: Boxed values and equality
When comparing wrapper types such as Integers, Longs or Booleans using == or !=, you're comparing them as references, not as values.
If two variables point at different objects, they will not == each other, even if the objects represent the same value.
Example: Comparing different Integer objects using
==and!=.Integer i = new Integer(10); Integer j = new Integer(10); System.out.println(i == j); // false System.out.println(i != j); // true
The solution is to compare the values using .equals()…
Example: Compare objects using
.equals(…)Integer i = new Integer(10); Integer j = new Integer(10); System.out.println(i.equals(j)); // true
…or to unbox the operands explicitly.
Example: Force unboxing by casting:
Integer i = new Integer(10); Integer j = new Integer(10); System.out.println((int) i == (int) j); // true
If they were simple int types, it would work.
For Integer use .intValue() or compareTo(Object other) or equals(Object other) in your comparison.
Change all the || to &&:
if (!balance[j].equals("+") && !balance[j].equals("-") &&
!balance[j].equals("(") && !balance[j].equals(")"))
Also, both the starting value of j and the loop's terminal condition look iffy.
Use
if(!((balance[j].equals("+")) || (balance[j].equals("-")) || (balance[j].equals("(")) || (balance[j].equals(")"))))
and
for(int j=0 ; j<=balance.length-1 ; j++)
In your case:
Right: if ( x.equals(y) )
Wrong: if ( x == y )
If the equals API is not working, then you've overridden it in your Card class, and you've implemented it wrong.
If you haven't overridden it, well then do it:
public class Card
{
...
@Override
public boolean equals(final Object obj)
{
if (obj == this)
return true;
if (obj == null || !(obj instanceof Card))
return false;
Card otherCard = (Card) obj;
if (otherCard.score != this.score) return false;
if (otherCard.symbol != this.symbol) return false;
if (!otherCard.warna.equals(this.warna)) return false;
if (!otherCard.type.equals(this.type)) return false;
if (!otherCard.value.equals(this.value)) return false;
return true;
}
}
This is not using the equals() method, but is testing reference equality of the 2 instances:
if(x==y)
You need to call the equals() method if you want to use it.
UPDATE:
The equals() test is not working because you have not overridden the default Object.equals() method, which only tests reference equality.
Your class currently extends only Object class and in Object class equals method looks like this
public boolean equals(Object obj) {
return (this == obj);
}
What you need is to override this method, for example like this
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (id == other.id)
return true;
if (id == null)
return false;
if (other.id == null)
return false;
if (!this.id.equals(other.id))
return false;
return true;
}
Also when you override equals you probably should override hashCode method, but this is not subject of your question. You can read more about it here.
If you don't override equals() on the object, you are comparing two different memory references. So override equals() to compare the id fields.
(small) Integer instances are cached, so the invariant x == y is holded for small instances (actually -127 +128, depends on JVM):
Integer a = 10;
Integer b = 10;
assert(a == b); // ok, same instance reused
a = 1024;
b = 1024;
assert(a == b); // fail, not the same instance....
assert(a.equals(b)); // but same _value_
EDIT
4) and 5) yield false because equals check types: X is an Integer whereas Y is a Short. This is the java.lang.Integer#equals method:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
The reason for
X == y
being true has to do with binary numeric promotion. When at least one operand to the equality operator is convertible to a numeric type, the numeric equality operator is used. First, the first operand is unboxed. Then, both operands are converted to int.
While
X.equals(y)
is a normal function call. As has been mentioned, y will be autoboxed to a Short object. Integer.equals always returns false if the argument is not an Integer instance. This can be easily seen by inspecting the implementation.
One could argue that this is a design flaw.
Yes, == with objects is a reference comparison* (checks if the operands are references to the same object), while equals is whatever the class involved defines it to mean (within the requirements documented for equals). Some classes define equals as being the same as ==, including Java's arrays. (Because they don't override the default implementation from Object.equals, which uses ==.)
If you want to compare Java arrays based on the equality of their contents, you use Arrays.equals instead.
Your experiment would have worked if you used a class that defined equals in a useful way, you were just unlucky picking arrays. It's a bit tricky to find a class in the JVM to use for this experiment, because so many either don't implement equals (like arrays) or could be confusing because there are several immutable classes which may reuse instances (although not if you explicitly use new; but I don't want to go down a path of having you use new with something you probably shouldn't, like String; more on that here). I'm going to give up on picking a good example and use the slightly old class SimpleDateFormat:
DateFormat a = new SimpleDateFormat("yyyy-MM-dd");
DateFormat b = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(a == b ? "== Same" : "== Different");
System.out.println(a.equals(b) ? "equals Same" : "equals Different");
That outputs
== Different equals Same
because SimpleDateFormat defines equals to check that the other object is also a SimpleDateFormat with the same formatting.
Live example
Re your comment on the question:
I have someone the answer points but I only get the == part, if .equals is checking the content, how come the code didnt print "same" for the second if
Because equals doesn't, necessarily, check content. It only does if a class overrides the default Object.equals (which just uses ==) and implements a content check. Arrays don't. (One could argue that they should have, but they don't.) Other classes, like SimpleDateFormat and String and Integer and HashMap do.
In essence: == is always a reference comparison. equals may or may not be a contents comparison, depending on what class you're using it on.
So for instance, say we have this class:
class Example1
{
private int content;
Example1(int content) {
this.content = content;
}
public static void main (String[] args) throws java.lang.Exception
{
Example1 a = new Example1(42);
Example1 b = new Example1(42);
System.out.println(a == b ? "== Same" : "== Different");
System.out.println(a.equals(b) ? "equals Same" : "equals Different");
}
}
Since that class doesn't override equals, you'll get the same answer ("Different") for both == and equals. Live Example.
But if we override equals to define what it would mean for two instances to be equal (in this case: because they have the same content):
class Example2
{
private int content;
Example2(int content) {
this.content = content;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !obj.getClass().equals(this.getClass())) {
return false;
}
Example2 other = (Example2)obj;
return this.content == other.content;
}
@Override
public int hashCode() {
return this.content;
}
public static void main (String[] args) throws java.lang.Exception
{
Example2 a = new Example2(42);
Example2 b = new Example2(42);
System.out.println(a == b ? "== Same" : "== Different");
System.out.println(a.equals(b) ? "equals Same" : "equals Different");
}
}
Now equals says two instances with the same content are the same, because the class defines what that means. Live Example. (Also note that when overriding equals, you must override hashCode, which is why I've done so above.)
* More generally, == tests if the values of its operands are the same. The value in the case of reference types is an object reference, and two object reference values are only the same when they refer to the same object are are only different when they refer to different objects (or one of them is null; not referring to an object at all).
To create object you need some portion of memory to store it.
Operator == checks if two variables point to the same memory block. That is they points to the same object instance (they are one person under different aliases).
equals() is a method and checks equality by some algorithm. Meaning two object contain the same data (they are different persons but with the same face, twins for example). Default implementation for java.lang.Object#equals is
public boolean equals(Object obj) {
return (this == obj);
}
Using you IDE you can ensure that equals for an array is actually java.lang.Object#equals. To check two arrays for equality you should use Arrays.equals. It has also a lot of other useful methods for manipulating with arrays. It is a good idea to check this class first when you need to do something with an array. It saves much time and code lines.
EDITED
Arrays (int[], float[], String[], AnyClass[]) does not implement custom equals method. So for array and for any your custom class equals() and == do same operation unless you override equals() and provide custom comparison. Like
public class Person {
public String name;
public String surname;
public Person(String name, String surname) {
this.name = name;
this.surname = surname;
}
public boolean equals(Object thatObj) {
if (thatObj instanceof Person) {
Person that = (Person) thatObj;
return this.name.equals(that.name) &&
this.surname.equals(that.surname);
}
return false;
}
}
Is == checking is slower than equals() in Java?
Comparing two object references is most of time faster but it doesn't make always sense to compare objects in this way.
1) As you compare two int (primitive), the == operator should be favored :
int i = ...;
if(i == 1){
It is the most natural and efficient way.
2) As you compare two Integer(object), the equals()way should be favored:
Integer i = ...
Integer j = ...
if(i.equals(j)){
You have not to use == as == will compare the identity of the objects and it could work in some range but not in all and it depends also on how Integers were instantiated.
So just don't use == in this case.
3) As you compare an Integer with an int, the equals()way should be avoided.
Integer i = ...
if(i.equals(1)){
works but should be avoided as it boxes int 1 to a Integer 1 before invoking equals().
And the equals() method invokes intValue() on the passed Integer argument to equals().
In brief, it performs checks and computations that could be avoided.
You have two ways to handle this comparison case that should have similar performance :
Using the
==comparison :Integer i = ... if (a==1){It unboxes the
Integerto anintand compares directly theintvalue with==using the
intValue()of the wrapper and comparing then two primitiveints with==** (we come back to the first case) :Integer i = if(i.intValue() == 1)){
Generally, the automatic unboxing performed by the JVM from an Integer to an int invokes intValue() .
The following is not valid:
int i;
int j;
if (i.equals(j))
because primitives are not objects. They have no methods at all; not even equals.
Java has the concept of boxed primitives which are classes which encapsulate a primitive and provide methods you can call. For int the box class is Integer. Using these classes is always slower than using the primitive version but it's sometimes unavoidable. There is an overhead, however slight, to creating objects and making method calls. Primitive values don't suffer from this.
Basically, use primitives unless there's a compelling reason not to.
If the types involved are Integer:
Integer i;
Integer j;
if (i.equals(j))
then you do have an equals method. However, you have (effectively) no choice but to call equals to make this comparison because == is reference equality. You can read more about that here: How to properly compare two Integers in Java? John Skeet's answer talks a little bit about the most efficient way to compare two Integers.
In Java, the equals() method that is inherited from Object is:
public boolean equals(Object other);
In other words, the parameter must be of type Object. This is called overriding; your method public boolean equals(Book other) does what is called overloading to the equals() method.
The ArrayList uses overridden equals() methods to compare contents (e.g. for its contains() and equals() methods), not overloaded ones. In most of your code, calling the one that didn't properly override Object's equals was fine, but not compatible with ArrayList.
So, not overriding the method correctly can cause problems.
I override equals the following everytime:
@Override
public boolean equals(Object other){
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof MyClass)) return false;
MyClass otherMyClass = (MyClass)other;
...test other properties here...
}
The use of the @Override annotation can help a ton with silly mistakes.
Use it whenever you think you are overriding a super class' or interface's method. That way, if you do it the wrong way, you will get a compile error.
If you use eclipse just go to the top menu
Source --> Generate equals() and hashCode()