why 2 objects of Integer class in Java cannot be equal - java

my code is:
public class Box
{
public static void main(String[] args)
{
Integer z = new Integer(43);
z++;
Integer h = new Integer(44);
System.out.println("z == h -> " + (h == z ));
}
}
Output:-
z == h -> false
why the output is false when the values of both the objects is equal?
Is there any other way in which we can make the objects equal?

No. Use h.equals(z) instead of h == z to get the equality behavior you expect.

h == z would work only if you assign the value via auto-boxing (i.e Integer a = 43) and the value is in between -128 and 127 (cached values), i.e:
Integer a = 44;
Integer b = 44;
System.out.println("a == b -> " + (a == b));
OUTPUT:
a == b -> true
If the value is out of the range [-128, 127], then it returns false
Integer a = 1000;
Integer b = 1000;
System.out.println("a == b -> " + (a == b));
OUTPUT:
a == b -> false
However, the right way to compare two objects is to use Integer.equals() method.

Integer is Object not primitive (int) And Object equality compare with equals method.
When you do z == h it will not unbox into int value unless it checks both Integer reference(z & h) are referring same reference or not.
As it is derived in documentation -
The result is true if and only if the argument is not null and is an
Integer object that contains the same int value as this object.
System.out.println("z == h -> " + h.equals( z));
It will print true.

You are trying to compare two different object and not their values. z and h points to two different Integer object which hold same value.
z == h
Will check if two objects are equal. So it will return false.
If you want to compare values stored by Integer object use equals method.
Integer z = new Integer(43); // Object1 is created with value as 43.
z++; // Now object1 holds 44.
Integer h = new Integer(44); // Object2 is created with value as 44.
So at the end we have two different Integer object ie object1 and object2 with value as 44.
Now
z = h
This will check if objects pointed by z and h is same. ie object1 == object2
which is false.
If you do
Integer z = new Integer(43); // Object1 is created with value as 43.
z++; // Now object1 holds 44. Z pointing to Object1
Integer h = z; // Now h is pointing to same object as z.
Now
z == h
will return true.
This might help http://www.programmerinterview.com/index.php/java-questions/java-whats-the-difference-between-equals-and/

Integer is an object, not a primitive. If z & h were primitives, == would work just fine. When dealing with objects, the == operator doesn't check for equality; it checks if the two references point to the same object.
As such, use z.equals(h); or h.equals(z); These should return true.

Read this: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html
Integer is Object you compare address/references/pointers of objects not values.
Integer a = Integer(1);
Integer b = Integer(1);
a == b; // false
a.compareTo(b); // true

check to make sure you can use z++ on the Integer object.

Related

Why is this HackerRank problem working fine with 'int' but not with 'Integer'? [duplicate]

I know that if you compare a boxed primitive Integer with a constant such as:
Integer a = 4;
if (a < 5)
a will automatically be unboxed and the comparison will work.
However, what happens when you are comparing two boxed Integers and want to compare either equality or less than/greater than?
Integer a = 4;
Integer b = 5;
if (a == b)
Will the above code result in checking to see if they are the same object, or will it auto-unbox in that case?
What about:
Integer a = 4;
Integer b = 5;
if (a < b)
?
No, == between Integer, Long etc will check for reference equality - i.e.
Integer x = ...;
Integer y = ...;
System.out.println(x == y);
this will check whether x and y refer to the same object rather than equal objects.
So
Integer x = new Integer(10);
Integer y = new Integer(10);
System.out.println(x == y);
is guaranteed to print false. Interning of "small" autoboxed values can lead to tricky results:
Integer x = 10;
Integer y = 10;
System.out.println(x == y);
This will print true, due to the rules of boxing (JLS section 5.1.7). It's still reference equality being used, but the references genuinely are equal.
If the value p being boxed is an integer literal of type int between
-128 and 127 inclusive (§3.10.1), or the boolean literal true or false (§3.10.3), or a character literal between '\u0000' and '\u007f'
inclusive (§3.10.4), then let a and b be the results of any two boxing
conversions of p. It is always the case that a == b.
Personally I'd use:
if (x.intValue() == y.intValue())
or
if (x.equals(y))
As you say, for any comparison between a wrapper type (Integer, Long etc) and a numeric type (int, long etc) the wrapper type value is unboxed and the test is applied to the primitive values involved.
This occurs as part of binary numeric promotion (JLS section 5.6.2). Look at each individual operator's documentation to see whether it's applied. For example, from the docs for == and != (JLS 15.21.1):
If the operands of an equality
operator are both of numeric type, or
one is of numeric type and the other
is convertible (§5.1.8) to numeric
type, binary numeric promotion is
performed on the operands (§5.6.2).
and for <, <=, > and >= (JLS 15.20.1)
The type of each of the operands of a
numerical comparison operator must be
a type that is convertible (§5.1.8) to
a primitive numeric type, or a
compile-time error occurs. Binary
numeric promotion is performed on the
operands (§5.6.2). If the promoted
type of the operands is int or long,
then signed integer comparison is
performed; if this promoted type is
float or double, then floating-point
comparison is performed.
Note how none of this is considered as part of the situation where neither type is a numeric type.
== will still test object equality. It is easy to be fooled, however:
Integer a = 10;
Integer b = 10;
System.out.println(a == b); //prints true
Integer c = new Integer(10);
Integer d = new Integer(10);
System.out.println(c == d); //prints false
Your examples with inequalities will work since they are not defined on Objects. However, with the == comparison, object equality will still be checked. In this case, when you initialize the objects from a boxed primitive, the same object is used (for both a and b). This is an okay optimization since the primitive box classes are immutable.
Since Java 1.7 you can use Objects.equals:
java.util.Objects.equals(oneInteger, anotherInteger);
Returns true if the arguments are equal to each other and false
otherwise. Consequently, if both arguments are null, true is returned
and if exactly one argument is null, false is returned. Otherwise,
equality is determined by using the equals method of the first
argument.
We should always go for the equals() method for comparison of two integers. It's the recommended practice.
If we compare two integers using == that would work for certain range of integer values (Integer from -128 to 127) due to the JVM's internal optimisation.
Please see examples:
Case 1:
Integer a = 100;
Integer b = 100;
if (a == b) {
System.out.println("a and b are equal");
} else {
System.out.println("a and b are not equal");
}
In above case JVM uses value of a and b from cached pool and return the same object instance(therefore memory address) of integer object and we get both are equal.Its an optimisation JVM does for certain range values.
Case 2: In this case, a and b are not equal because it does not come with the range from -128 to 127.
Integer a = 220;
Integer b = 220;
if (a == b) {
System.out.println("a and b are equal");
} else {
System.out.println("a and b are not equal");
}
Proper way:
Integer a = 200;
Integer b = 200;
System.out.println("a == b? " + a.equals(b)); // true
tl;dr my opinion is to use a unary + to trigger the unboxing on one of the operands when checking for value equality, and simply use the maths operators otherwise. Rationale follows:
It has been mentioned already that == comparison for Integer is identity comparison, which is usually not what a programmer want, and that the aim is to do value comparison; still, I've done a little science about how to do that comparison most efficiently, both in term of code compactness, correctness and speed.
I used the usual bunch of methods:
public boolean method1() {
Integer i1 = 7, i2 = 5;
return i1.equals( i2 );
}
public boolean method2() {
Integer i1 = 7, i2 = 5;
return i1.intValue() == i2.intValue();
}
public boolean method3() {
Integer i1 = 7, i2 = 5;
return i1.intValue() == i2;
}
public boolean method4() {
Integer i1 = 7, i2 = 5;
return i1 == +i2;
}
public boolean method5() { // obviously not what we want..
Integer i1 = 7, i2 = 5;
return i1 == i2;
}
and got this code after compilation and decompilation:
public boolean method1() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
return var1.equals( var2 );
}
public boolean method2() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2.intValue() == var1.intValue() ) {
return true;
} else {
return false;
}
}
public boolean method3() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2.intValue() == var1.intValue() ) {
return true;
} else {
return false;
}
}
public boolean method4() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2.intValue() == var1.intValue() ) {
return true;
} else {
return false;
}
}
public boolean method5() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2 == var1 ) {
return true;
} else {
return false;
}
}
As you can easily see, method 1 calls Integer.equals() (obviously), methods 2-4 result in exactly the same code, unwrapping the values by means of .intValue() and then comparing them directly, and method 5 just triggers an identity comparison, being the incorrect way to compare values.
Since (as already mentioned by e.g. JS) equals() incurs an overhead (it has to do instanceof and an unchecked cast), methods 2-4 will work with exactly the same speed, noticingly better than method 1 when used in tight loops, since HotSpot is not likely to optimize out the casts & instanceof.
It's quite similar with other comparison operators (e.g. </>) - they will trigger unboxing, while using compareTo() won't - but this time, the operation is highly optimizable by HS since intValue() is just a getter method (prime candidate to being optimized out).
In my opinion, the seldom used version 4 is the most concise way - every seasoned C/Java developer knows that unary plus is in most cases equal to cast to int/.intValue() - while it may be a little WTF moment for some (mostly those who didn't use unary plus in their lifetime), it arguably shows the intent most clearly and most tersely - it shows that we want an int value of one of the operands, forcing the other value to unbox as well. It is also unarguably most similar to the regular i1 == i2 comparison used for primitive int values.
My vote goes for i1 == +i2 & i1 > i2 style for Integer objects, both for performance & consistency reasons. It also makes the code portable to primitives without changing anything other than the type declaration. Using named methods seems like introducing semantic noise to me, similar to the much-criticized bigInt.add(10).multiply(-3) style.
== checks for reference equality, however when writing code like:
Integer a = 1;
Integer b = 1;
Java is smart enough to reuse the same immutable for a and b, so this is true: a == b. Curious, I wrote a small example to show where java stops optimizing in this way:
public class BoxingLol {
public static void main(String[] args) {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
Integer a = i;
Integer b = i;
if (a != b) {
System.out.println("Done: " + i);
System.exit(0);
}
}
System.out.println("Done, all values equal");
}
}
When I compile and run this (on my machine), I get:
Done: 128
Calling
if (a == b)
Will work most of the time, but it's not guaranteed to always work, so do not use it.
The most proper way to compare two Integer classes for equality, assuming they are named 'a' and 'b' is to call:
if(a != null && a.equals(b)) {
System.out.println("They are equal");
}
You can also use this way which is slightly faster.
if(a != null && b != null && (a.intValue() == b.intValue())) {
System.out.println("They are equal");
}
On my machine 99 billion operations took 47 seconds using the first method, and 46 seconds using the second method. You would need to be comparing billions of values to see any difference.
Note that 'a' may be null since it's an Object. Comparing in this way will not cause a null pointer exception.
For comparing greater and less than, use
if (a != null && b!=null) {
int compareValue = a.compareTo(b);
if (compareValue > 0) {
System.out.println("a is greater than b");
} else if (compareValue < 0) {
System.out.println("b is greater than a");
} else {
System.out.println("a and b are equal");
}
} else {
System.out.println("a or b is null, cannot compare");
}
In my case I had to compare two Integers for equality where both of them could be null. I searched similar topics, but I didn't find anything elegant for this. I came up with simple utility function:
public static boolean integersEqual(Integer i1, Integer i2) {
if (i1 == null && i2 == null) {
return true;
}
if (i1 == null && i2 != null) {
return false;
}
if (i1 != null && i2 == null) {
return false;
}
return i1.intValue() == i2.intValue();
}
// Considering null is less than not-null
public static int integersCompare(Integer i1, Integer i2) {
if (i1 == null && i2 == null) {
return 0;
}
if (i1 == null && i2 != null) {
return -1;
}
return i1.compareTo(i2);
}
Because a comparison method has to be done based on type int (x==y) or class Integer (x.equals(y)) with the right operator:
public class Example {
public static void main(String[] args) {
int[] arr = {-32735, -32735, -32700, -32645, -32645, -32560, -32560};
for(int j=1; j<arr.length-1; j++)
if((arr[j-1] != arr[j]) && (arr[j] != arr[j+1]))
System.out.println("int>" + arr[j]);
Integer[] I_arr = {-32735, -32735, -32700, -32645, -32645, -32560, -32560};
for(int j=1; j<I_arr.length-1; j++)
if((!I_arr[j-1].equals(I_arr[j])) && (!I_arr[j].equals(I_arr[j+1])))
System.out.println("Interger>" + I_arr[j]);
}
}
This method compares two Integer's with a null check. See the tests.
public static boolean compare(Integer int1, Integer int2) {
if(int1!=null) {
return int1.equals(int2);
} else {
return int2==null;
}
//inline version:
//return (int1!=null) ? int1.equals(int2) : int2==null;
}
//results:
System.out.println(compare(1,1)); //true
System.out.println(compare(0,1)); //false
System.out.println(compare(1,0)); //false
System.out.println(compare(null,0)); //false
System.out.println(compare(0,null)); //false
System.out.println(compare(null,null)); //true

Java Integer Wrapper behavior [duplicate]

I know that if you compare a boxed primitive Integer with a constant such as:
Integer a = 4;
if (a < 5)
a will automatically be unboxed and the comparison will work.
However, what happens when you are comparing two boxed Integers and want to compare either equality or less than/greater than?
Integer a = 4;
Integer b = 5;
if (a == b)
Will the above code result in checking to see if they are the same object, or will it auto-unbox in that case?
What about:
Integer a = 4;
Integer b = 5;
if (a < b)
?
No, == between Integer, Long etc will check for reference equality - i.e.
Integer x = ...;
Integer y = ...;
System.out.println(x == y);
this will check whether x and y refer to the same object rather than equal objects.
So
Integer x = new Integer(10);
Integer y = new Integer(10);
System.out.println(x == y);
is guaranteed to print false. Interning of "small" autoboxed values can lead to tricky results:
Integer x = 10;
Integer y = 10;
System.out.println(x == y);
This will print true, due to the rules of boxing (JLS section 5.1.7). It's still reference equality being used, but the references genuinely are equal.
If the value p being boxed is an integer literal of type int between
-128 and 127 inclusive (§3.10.1), or the boolean literal true or false (§3.10.3), or a character literal between '\u0000' and '\u007f'
inclusive (§3.10.4), then let a and b be the results of any two boxing
conversions of p. It is always the case that a == b.
Personally I'd use:
if (x.intValue() == y.intValue())
or
if (x.equals(y))
As you say, for any comparison between a wrapper type (Integer, Long etc) and a numeric type (int, long etc) the wrapper type value is unboxed and the test is applied to the primitive values involved.
This occurs as part of binary numeric promotion (JLS section 5.6.2). Look at each individual operator's documentation to see whether it's applied. For example, from the docs for == and != (JLS 15.21.1):
If the operands of an equality
operator are both of numeric type, or
one is of numeric type and the other
is convertible (§5.1.8) to numeric
type, binary numeric promotion is
performed on the operands (§5.6.2).
and for <, <=, > and >= (JLS 15.20.1)
The type of each of the operands of a
numerical comparison operator must be
a type that is convertible (§5.1.8) to
a primitive numeric type, or a
compile-time error occurs. Binary
numeric promotion is performed on the
operands (§5.6.2). If the promoted
type of the operands is int or long,
then signed integer comparison is
performed; if this promoted type is
float or double, then floating-point
comparison is performed.
Note how none of this is considered as part of the situation where neither type is a numeric type.
== will still test object equality. It is easy to be fooled, however:
Integer a = 10;
Integer b = 10;
System.out.println(a == b); //prints true
Integer c = new Integer(10);
Integer d = new Integer(10);
System.out.println(c == d); //prints false
Your examples with inequalities will work since they are not defined on Objects. However, with the == comparison, object equality will still be checked. In this case, when you initialize the objects from a boxed primitive, the same object is used (for both a and b). This is an okay optimization since the primitive box classes are immutable.
Since Java 1.7 you can use Objects.equals:
java.util.Objects.equals(oneInteger, anotherInteger);
Returns true if the arguments are equal to each other and false
otherwise. Consequently, if both arguments are null, true is returned
and if exactly one argument is null, false is returned. Otherwise,
equality is determined by using the equals method of the first
argument.
We should always go for the equals() method for comparison of two integers. It's the recommended practice.
If we compare two integers using == that would work for certain range of integer values (Integer from -128 to 127) due to the JVM's internal optimisation.
Please see examples:
Case 1:
Integer a = 100;
Integer b = 100;
if (a == b) {
System.out.println("a and b are equal");
} else {
System.out.println("a and b are not equal");
}
In above case JVM uses value of a and b from cached pool and return the same object instance(therefore memory address) of integer object and we get both are equal.Its an optimisation JVM does for certain range values.
Case 2: In this case, a and b are not equal because it does not come with the range from -128 to 127.
Integer a = 220;
Integer b = 220;
if (a == b) {
System.out.println("a and b are equal");
} else {
System.out.println("a and b are not equal");
}
Proper way:
Integer a = 200;
Integer b = 200;
System.out.println("a == b? " + a.equals(b)); // true
tl;dr my opinion is to use a unary + to trigger the unboxing on one of the operands when checking for value equality, and simply use the maths operators otherwise. Rationale follows:
It has been mentioned already that == comparison for Integer is identity comparison, which is usually not what a programmer want, and that the aim is to do value comparison; still, I've done a little science about how to do that comparison most efficiently, both in term of code compactness, correctness and speed.
I used the usual bunch of methods:
public boolean method1() {
Integer i1 = 7, i2 = 5;
return i1.equals( i2 );
}
public boolean method2() {
Integer i1 = 7, i2 = 5;
return i1.intValue() == i2.intValue();
}
public boolean method3() {
Integer i1 = 7, i2 = 5;
return i1.intValue() == i2;
}
public boolean method4() {
Integer i1 = 7, i2 = 5;
return i1 == +i2;
}
public boolean method5() { // obviously not what we want..
Integer i1 = 7, i2 = 5;
return i1 == i2;
}
and got this code after compilation and decompilation:
public boolean method1() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
return var1.equals( var2 );
}
public boolean method2() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2.intValue() == var1.intValue() ) {
return true;
} else {
return false;
}
}
public boolean method3() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2.intValue() == var1.intValue() ) {
return true;
} else {
return false;
}
}
public boolean method4() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2.intValue() == var1.intValue() ) {
return true;
} else {
return false;
}
}
public boolean method5() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2 == var1 ) {
return true;
} else {
return false;
}
}
As you can easily see, method 1 calls Integer.equals() (obviously), methods 2-4 result in exactly the same code, unwrapping the values by means of .intValue() and then comparing them directly, and method 5 just triggers an identity comparison, being the incorrect way to compare values.
Since (as already mentioned by e.g. JS) equals() incurs an overhead (it has to do instanceof and an unchecked cast), methods 2-4 will work with exactly the same speed, noticingly better than method 1 when used in tight loops, since HotSpot is not likely to optimize out the casts & instanceof.
It's quite similar with other comparison operators (e.g. </>) - they will trigger unboxing, while using compareTo() won't - but this time, the operation is highly optimizable by HS since intValue() is just a getter method (prime candidate to being optimized out).
In my opinion, the seldom used version 4 is the most concise way - every seasoned C/Java developer knows that unary plus is in most cases equal to cast to int/.intValue() - while it may be a little WTF moment for some (mostly those who didn't use unary plus in their lifetime), it arguably shows the intent most clearly and most tersely - it shows that we want an int value of one of the operands, forcing the other value to unbox as well. It is also unarguably most similar to the regular i1 == i2 comparison used for primitive int values.
My vote goes for i1 == +i2 & i1 > i2 style for Integer objects, both for performance & consistency reasons. It also makes the code portable to primitives without changing anything other than the type declaration. Using named methods seems like introducing semantic noise to me, similar to the much-criticized bigInt.add(10).multiply(-3) style.
== checks for reference equality, however when writing code like:
Integer a = 1;
Integer b = 1;
Java is smart enough to reuse the same immutable for a and b, so this is true: a == b. Curious, I wrote a small example to show where java stops optimizing in this way:
public class BoxingLol {
public static void main(String[] args) {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
Integer a = i;
Integer b = i;
if (a != b) {
System.out.println("Done: " + i);
System.exit(0);
}
}
System.out.println("Done, all values equal");
}
}
When I compile and run this (on my machine), I get:
Done: 128
Calling
if (a == b)
Will work most of the time, but it's not guaranteed to always work, so do not use it.
The most proper way to compare two Integer classes for equality, assuming they are named 'a' and 'b' is to call:
if(a != null && a.equals(b)) {
System.out.println("They are equal");
}
You can also use this way which is slightly faster.
if(a != null && b != null && (a.intValue() == b.intValue())) {
System.out.println("They are equal");
}
On my machine 99 billion operations took 47 seconds using the first method, and 46 seconds using the second method. You would need to be comparing billions of values to see any difference.
Note that 'a' may be null since it's an Object. Comparing in this way will not cause a null pointer exception.
For comparing greater and less than, use
if (a != null && b!=null) {
int compareValue = a.compareTo(b);
if (compareValue > 0) {
System.out.println("a is greater than b");
} else if (compareValue < 0) {
System.out.println("b is greater than a");
} else {
System.out.println("a and b are equal");
}
} else {
System.out.println("a or b is null, cannot compare");
}
In my case I had to compare two Integers for equality where both of them could be null. I searched similar topics, but I didn't find anything elegant for this. I came up with simple utility function:
public static boolean integersEqual(Integer i1, Integer i2) {
if (i1 == null && i2 == null) {
return true;
}
if (i1 == null && i2 != null) {
return false;
}
if (i1 != null && i2 == null) {
return false;
}
return i1.intValue() == i2.intValue();
}
// Considering null is less than not-null
public static int integersCompare(Integer i1, Integer i2) {
if (i1 == null && i2 == null) {
return 0;
}
if (i1 == null && i2 != null) {
return -1;
}
return i1.compareTo(i2);
}
Because a comparison method has to be done based on type int (x==y) or class Integer (x.equals(y)) with the right operator:
public class Example {
public static void main(String[] args) {
int[] arr = {-32735, -32735, -32700, -32645, -32645, -32560, -32560};
for(int j=1; j<arr.length-1; j++)
if((arr[j-1] != arr[j]) && (arr[j] != arr[j+1]))
System.out.println("int>" + arr[j]);
Integer[] I_arr = {-32735, -32735, -32700, -32645, -32645, -32560, -32560};
for(int j=1; j<I_arr.length-1; j++)
if((!I_arr[j-1].equals(I_arr[j])) && (!I_arr[j].equals(I_arr[j+1])))
System.out.println("Interger>" + I_arr[j]);
}
}
This method compares two Integer's with a null check. See the tests.
public static boolean compare(Integer int1, Integer int2) {
if(int1!=null) {
return int1.equals(int2);
} else {
return int2==null;
}
//inline version:
//return (int1!=null) ? int1.equals(int2) : int2==null;
}
//results:
System.out.println(compare(1,1)); //true
System.out.println(compare(0,1)); //false
System.out.println(compare(1,0)); //false
System.out.println(compare(null,0)); //false
System.out.println(compare(0,null)); //false
System.out.println(compare(null,null)); //true

How to use comparison operators like >, =, < on BigDecimal

I have a domain class with unitPrice set as BigDecimal data type. Now I am trying to create a method to compare price but it seems like I can't have comparison operators in BigDecimal data type. Do I have to change data type or is there other way around?
To be short:
firstBigDecimal.compareTo(secondBigDecimal) < 0 // "<"
firstBigDecimal.compareTo(secondBigDecimal) > 0 // ">"
firstBigDecimal.compareTo(secondBigDecimal) == 0 // "=="
firstBigDecimal.compareTo(secondBigDecimal) >= 0 // ">="
Every object of the Class BigDecimal has a method compareTo you can use to compare it to another BigDecimal. The result of compareTo is then compared > 0, == 0 or < 0 depending on what you need. Read the documentation and you will find out.
The operators ==, <, > and so on can only be used on primitive data types like int, long, double or their wrapper classes like Integerand Double.
From the documentation of compareTo:
Compares this BigDecimal with the specified BigDecimal.
Two BigDecimal
objects that are equal in value but have a different scale (like 2.0
and 2.00) are considered equal by this method. This method is provided
in preference to individual methods for each of the six boolean
comparison operators (<, ==, >, >=, !=, <=). The suggested idiom for
performing these comparisons is: (x.compareTo(y) <op> 0), where <op>
is one of the six comparison operators.
Returns:
-1, 0, or 1 as this BigDecimal is numerically less than, equal to, or greater than val.
Use the compareTo method of BigDecimal :
public int compareTo(BigDecimal val) Compares this BigDecimal with the
specified BigDecimal.
Returns:
-1, 0, or 1 as this BigDecimal is numerically less than, equal to, or greater than val.
Here is an example for all six boolean comparison operators (<, ==, >, >=, !=, <=):
BigDecimal big10 = new BigDecimal(10);
BigDecimal big20 = new BigDecimal(20);
System.out.println(big10.compareTo(big20) < -1); // false
System.out.println(big10.compareTo(big20) <= -1); // true
System.out.println(big10.compareTo(big20) == -1); // true
System.out.println(big10.compareTo(big20) >= -1); // true
System.out.println(big10.compareTo(big20) > -1); // false
System.out.println(big10.compareTo(big20) != -1); // false
System.out.println(big10.compareTo(big20) < 0); // true
System.out.println(big10.compareTo(big20) <= 0); // true
System.out.println(big10.compareTo(big20) == 0); // false
System.out.println(big10.compareTo(big20) >= 0); // false
System.out.println(big10.compareTo(big20) > 0); // false
System.out.println(big10.compareTo(big20) != 0); // true
System.out.println(big10.compareTo(big20) < 1); // true
System.out.println(big10.compareTo(big20) <= 1); // true
System.out.println(big10.compareTo(big20) == 1); // false
System.out.println(big10.compareTo(big20) >= 1); // false
System.out.println(big10.compareTo(big20) > 1); // false
System.out.println(big10.compareTo(big20) != 1); // true
You can use method named compareTo, x.compareTo(y). It will return 0 if x and y are equal, 1 if x is greater than y and -1 if x is smaller than y
Discussion
This thread has plenty of answers stating that the BigDecimal.compareTo(BigDecimal) method is the one to use to compare BigDecimal instances. I just wanted to add for anyone not experienced with using the BigDecimal.compareTo(BigDecimal) method: Be careful with how you create your BigDecimal instances. For example:
new BigDecimal(0.8) will create a BigDecimal instance with a value which is not exactly 0.8 and which has a scale of 50+,
new BigDecimal("0.8") will create a BigDecimal instance with a value which is exactly 0.8 and which has a scale of 1.
These two BigDecimal instances are unequal according to the BigDecimal.compareTo(BigDecimal) method because their values are unequal when the scale is not limited to a few decimal places.
Summary
Firstly, be careful to create your BigDecimal instances with the BigDecimal(String val) constructor or the BigDecimal.valueOf(double val) method rather than the BigDecimal(double val) constructor. Secondly, note that you can limit the scale of BigDecimal instances prior to comparing them by means of the BigDecimal.setScale(int newScale, RoundingMode roundingMode) method.
BigDecimal isn't a primitive, so you cannot use the <, > operators. However, since it's a Comparable, you can use the compareTo(BigDecimal) to the same effect. E.g.:
public class Domain {
private BigDecimal unitPrice;
public boolean isCheaperThan(BigDecimal other) {
return unitPirce.compareTo(other.unitPrice) < 0;
}
// etc...
}
Alternatively, if you're already using commons-lang3 (version 3.10 and up), you can leverage their ComparableUtils API like so:
import static org.apache.commons.lang3.compare.ComparableUtils.is;
var areEqual = is(first).equalTo(second);
var isGreater = is(first).greaterThan(second);
var isLess = is(first).lessThan(second);
var isBetween = is(first).between(second, third);
// etc.
Nowadays, most large projects include commons-lang3 as a dependency, anyway.
You can follow this utility static method and Operator enum for comparing the two numbers:
public static boolean check(BigDecimal firstNum, Operator operator, BigDecimal secondNum) {
switch (operator) {
case EQUALS:
return firstNum.compareTo(secondNum) == 0;
case LESS_THAN:
return firstNum.compareTo(secondNum) < 0;
case LESS_THAN_OR_EQUALS:
return firstNum.compareTo(secondNum) <= 0;
case GREATER_THAN:
return firstNum.compareTo(secondNum) > 0;
case GREATER_THAN_OR_EQUALS:
return firstNum.compareTo(secondNum) >= 0;
}
throw new IllegalArgumentException("Will never reach here");
}
public enum Operator {
LESS_THAN, LESS_THAN_OR_EQUALS, GREATER_THAN, GREATER_THAN_OR_EQUALS, EQUALS
}
Using com.ibm.etools.marshall.util.BigDecimalRange util class of IBM one can compare if BigDecimal in range.
boolean isCalculatedSumInRange = BigDecimalRange.isInRange(low, high, calculatedSum);
Below is an example to compare two BigDecimal values.
public class BigDecimalDemo {
public static void main(String[] args) {
// create 2 BigDecimal objects
BigDecimal bg1, bg2;
bg1 = new BigDecimal("10");
bg2 = new BigDecimal("20");
//create int object
int res;
res = bg1.compareTo(bg2); // compare bg1 with bg2
String str1 = "Both values are equal ";
String str2 = "First Value is greater ";
String str3 = "Second value is greater";
if( res == 0 )
System.out.println( str1 );
else if( res == 1 )
System.out.println( str2 );
else if( res == -1 )
System.out.println( str3 );
}
}

I need some help to understand this code in java

I stack in this code I do not understand what happens in some of its lines .. I commented next to each line I did not understand it ..
here is the code
public class C
{
boolean [] b = new boolean[3]; // Is this a vector of size 3 ?
int count = 0;
void set(boolean [] x, int i)
{
x[i] = true;
++count;
}
public static void main(String [] args)
{
C ba = new C();
ba.set(ba.b, 0); // what does ba.b do?
ba.set(ba.b, 2); // what does ba.b do?
ba.test();
}
void test()
{
if ( b[0] && b[1] | b[2] ) // what is this if statement do?
count++;
if ( b[1] && b[(++count - 2)] ) // what is this if statement do?
count += 7;
System.out.println("count = " + count);
}
}
Can you discribe to me what happens there ? thanks
boolean[] b = new boolean[3] is a boolean array with 3 data points
b[0] = true; //or false
b[1] = false; //or true
b[2] = true; //or false
int count = 0; is a variable of type int
void set(boolean [] x, int i) sets a boolean array to equal true in position one. For example
set(b,1)
would set the variables to
b[1] = true
count = 1
ba is an instance of your class C. In this case it allows you to call your method set(boolean [] x, int i) and your boolean array, b from your code
Finally the first if statement if(b[0]&&b[1]||b[2]) says if(the first position, b[0] in b is true and either position two, b[1], or the third position, b[2], is true) then add one to the count variable.
The second if statement if(b[1]&&b[++count-2]) says if(the second position in the array, b[1], is true and b[count-1] is true) then add 7 to the variable count.
The last line of test() says print out the value of the variable count to the command console
Edit
A vector is another method of storing values in Java but it is not limited to one datatype, such as int or double. For example
import java.util.*;
public class VectorDemo {
public static void main(String args[]) {
// initial size is 3, increment is 2
Vector v = new Vector(3, 2);
System.out.println("Initial size: " + v.size());
System.out.println("Initial capacity: " +
v.capacity());
v.addElement(new Integer(1));
v.addElement(new Integer(2));
System.out.println("Capacity after four additions: " +
v.capacity());
v.addElement(new Double(5.45));
System.out.println("Current capacity: " +
v.capacity());
v.addElement(new Double(6.08));
v.addElement(new Integer(7));
System.out.println("Current capacity: " +
v.capacity());
v.addElement(new Float(9.4));
v.addElement(new Integer(10));
System.out.println("Current capacity: " +
v.capacity());
v.addElement(new Integer(11));
v.addElement(new Integer(12));
System.out.println("First element: " +
(Integer)v.firstElement());
System.out.println("Last element: " +
(Integer)v.lastElement());
if(v.contains(new Integer(3)))
System.out.println("Vector contains 3.");
// enumerate the elements in the vector.
Enumeration vEnum = v.elements();
System.out.println("\nElements in vector:");
while(vEnum.hasMoreElements())
System.out.print(vEnum.nextElement() + " ");
System.out.println();
}
}
Whereas an array can only hold one type of data and its size is specified when it is declared. For example
int[] intArray = new int[2];
intArray[0] = 1;
intArray[1] = 250;
or it can be declared as
int[] intArray = {1,250};
See here for more information on Vectors and here for more information on Arrays.
If you have access to a debugger, put a break point at C ba = new C(); , and then step through, it will give you an idea of what this code is doing.
hope this helps.
boolean[] b = new boolean[3]; // Is this a vector of size 3 ?
Its an array of fix size holding 3 elements
ba.set(ba.b, 0); // what does ba.b do?
It sends reference of array b defined above which holds 3 element, so when you pass that value to set method, it sets b's 0th index to true.
ba.set(ba.b, 2); // what does ba.b do?
same as above
if (b[0] && b[1] | b[2]) // what is this if statement do?
treat it like (condition1 && condition2)
if (b[1] && b[(++count - 2)]) // what is this if statement do?
treat it like (condition1 && condition2) where you are saying if b[1] is true and b[count+1-2] is true too
b is an array of booleans
ba.b points to the objects instance variable b.
b[0] && b[1] | b[2] means if b[0] is true and b[1] is true xor b[3] is true
b[1] && b[(++count - 2) means if b[1] is true and b[count - 1] is true
Generally it is not a clear code.
Specifically:
boolean [] b = new boolean[3]; // Is this a vector of size 3 ?
Yes, this line define an array of 3 boolean values. Each single value could be accessed by using selector index, starting from 0 (i.e. b[0], b[1], b[2]).
ba.set(ba.b, 0); // what does ba.b do?
Then, ba is an instance of C class. Using ba.b it is possible to access the array b defined in C. Access to single values it is possible using selectors (i.e. b.ba[0], b.ba[1], b.ba[2]).
if ( b[0] && b[1] | b[2] ) // what is this if statement do?
This statement verifies a logical condition. In this case the condition is verified if both b[0] and b[1] values are TRUE, or simple b[2] is TRUE. Otherwise the condition is not verified.
if ( b[1] && b[(++count - 2)] ) // what is this if statement do?
Really, not a good programming example. This statement verify a condition but also has a side effect of increment the value of count variable. In this case the condition is verified if both b[1] is TRUE and b[(++count - 2)] are TRUE. If count < 1 the code will exit with a RuntimeException because we are trying to access the array outside the valid range of indexes.
boolean [] b = new boolean[3]; // Is this a vector of size 3 ?
Yes, this is how you create a new array (allocates memory on heap)
C ba = new C();
ba.set(ba.b, 0); // what does ba.b do?
ba is your instantiated object from class C, in the second line you call the object's set method, passing ba.b which is your object's boolean array of size 3, and an integer (0).
if ( b[0] && b[1] | b[2] ) // what is this if statement do?
So b[0] && b[1] will be true only if b[0] is true and b[1] is also true. Let c hold this partial result. The next condition will be c | b[2].
This operation is a bitwise operation, namely XOR. It will be true if the two operands are differs from each other, otherwise it will be false. (ex. true | true = false, false | false = false, but true | false = true)
if ( b[1] && b[(++count - 2)] ) // what is this if statement do?
Simply check if both b[1] and b[++count - 2] are true.
++count means increasing the count value by one before evaluating it. Assume count = 2. Then the right side is b[1].
boolean[] b=new boolean[3];
//creates a boolean array of length 3.
Indices-0,1,2
example: b[0]=true;
b[2]=false;
C ba=new C();
C bc=new C();
ba and bc are 2 objects of class C.They can also be termed as instances.Now every instance/object of a class has it's own copy of the instance variables and the functions in the class.
That means,object ba has it's own copy of the boolean array b and object bc has it's own unique copy of boolean array b.
You refer to ba's copy of array using
ba.b and bc's copy of array using bc.b.
Both the objects have a different copy and therefore,the value of b could be different for both.
Example:
b[0]=true; //ba's copy
b[0]=false; //bc's copy
Now if that boolean array b was static,it means that only one copy of b is shared between all the objects.So static objects can not be referred using object name.It's referred using class name.

Using the == operator twice in a if statement

Is it okay to do like this in java, does it work?
if (turtles.get(h).getX() == turtles.get(g).getX() == 450) {
//stuff here
}
Basically, i want to check if X is the same value as Y and that value should be 450.
No. What do you expect to happen there?
"a == b" evaluates into a boolean, so "int == (int == int)" would evaluate into "int == boolean", and you cannot compare and int and a boolean.
Besides, what kind of logic are you trying to do here? if ((a == b) && (b == c))?
No, it's not. This is because the result of a == b is a boolean. If you do a == b == c you are first comparing a == b which will return true or false and then comparing that truth value to c.
Not what you want to do, usually!
Note that this trick can work for assignment because the result of a = b is b (the new value of a) which means a = b = c or even (a = b) == c come in useful occasionally.
No. It is the same as (turtles.get(h).getX() == turtles.get(g).getX()) == 450 - "incomparable types". if(turtles.get(h).getX() == 450 && turtles.get(g).getX() == 450).
Or avoid all the less-readable (and error-prone) repetition with a helper method...
public boolean areEqual( int a, int b, int c )
{
return ( a == b ) && ( b == c ) ;
}
That won't work, because the == operator is binary.
And even if it worked sequentially, the first set would return a boolean, which won't work against the integer that follows.
No it won't work, as explained in the other posts. But you could do
if (turtles.get(h).getX() - turtles.get(g).getX() + 450 == 0)

Categories

Resources