Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
This is classical, but writing to Google did not give me hits.
My code:
Integer i = ..; // Sth is put from database.
if (i != 1) {
// do sth
} else {
// do not.
}
Case:
I know that this comparison is not correct java and I should compare:
if (i.intValue != 1) {}
or
if(!i.equals(1)) {}
but my code had the first one and I seem to get the true from somewhere, where the Integer is not 1 and when it is 1 there comes false.
Question:
What is happening there around?
but my code had the first one and I seem to get the true from somewhere, where the Integer is not 1 and when it is 1 there comes false.
If I understand your issue correctly, the following might explain the behavior:
Integer i = 1;
Integer j = new Integer(1);
Integer k = Integer.valueOf(1);
System.out.println(i == j); // false
System.out.println(i == k); // true
In other words, you can get both true or false when comparing with 1 depending on how the Integer was constructed. Integer.valueOf will reuse objects while new Integer will not.
If you indeed did the comparison with an integer literal (or with an int) then any Integer should be automatically unboxed by the compiler, and you should never get any surprises.
The compiler changes :
if (i != 1)
to
if(i.intValue()!=1)
Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.
See this link
if (i != 1) , if (i.intValue != 1) and if(!i.equals(1)) are all equal and will return the same value. The compiler will automatically unbox i, turning it into a primitive int.
Related
This question already has answers here:
Why does (i<=j && j<=i && i!=j) evaluate to TRUE?
(10 answers)
Closed 2 years ago.
I saw this exercise on a Java test, which finally led me to ask for ideas because there are some solutions I tried, but obviously won't solve the problem, due to Math conditions.
So the exercise:
Define S and T variables as it results an endless while loop below!
while(s <= t && s >= t && s != t)
{
}
think about OOP, in fact 0!=0 is false, but new Integer(0) != new Integer(0) is true because it's not the same reference.
so Integer S= new Integer(0); Integer T = new Integer(0);
should resolve your problem
here is answer :
This is not possible with primitive types. You can achieve it with boxed Integers:
Integer a = new Integer(1);
Integer b = new Integer(1);
The <= and >= comparisons will use the unboxed value 1, while the != will compare the references and will succeed since they are different objects.
you can check farther details in this link How can "a <= b && b <= a && a != b" be true?
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I would like to understand how can the int x be incremented inside an if (Boolean expression) for every loop iteration
How is that possible?? How does it work?
public class MethodsTest {
public static void main(String[] args) {
int x= 0;
for (int z = 0; z < 5; z++)
{
if(x++ > 2){
}
System.out.println(x);
}
}
}
the output will be
1
2
3
4
5
x++ is a compound assignment operator, which is equivalent to x = x + 1, with the side effect taking place after the evaluation. Therefore, the if statement is equivalent to a pair of statements like this:
if(x > 2) {
x = x + 1;
// At this point, the side effect has taken place, so x is greater than it was before the "if"
...
} else {
// The side effect takes place regardless of the condition, hence the "else"
x = x + 1;
}
Note that this code is forced to repeat the x = x + 1 part. Using ++ lets you avoid this repetition.
There is a pre-increment counterpart of x++ - namely, ++x. In this form the assignment takes place before the expression is evaluated, so the condition becomes
if ((x = x + 1) > 2) {
// Note that the condition above uses an assignment. An assignment is also an expression, with the result equal to
// the value assigned to the variable. Like all expressions, it can participate in a condition.
}
To break your notion that the condition of an if can't "do things", imagine that you have a function that returns a boolean, like:
boolean areThereCookies(int numCookies)
{
return numCookies > 0;
}
then you could use it in your if statement:
if (areThereCookies(cookies))
{
eatCookies(cookies);
}
However the method areThereCookies(int) that we are calling to evaluate the if condition could be making anything in the world. It could change variable values, read input, write output, steal cookies...
So the language is perfectly capable of "doing things" in the if evaluation. The other answers explain what your code was specifically doing.
Cheers.
You are allowed to have expressions inside a if statement as long as the expression resolves to a boolean. For example,
int i = 0
if (i = i + 1)
is not a valid expression inside an if statement because the expressions resolves to 1, which is an integer.
However,
int i = 0
if (2 == i = 2)
is a valid expression because 2 is first assigned to the variable i and then is compared to 2, and thus the expression resolves to “true”.
In your example if statement, you have a post-incremented variable x that is compared against 2 with the greater than operator, resulting in a boolean value, and thus it is a valid expression. Hotlinks has described what a post-incremented variable is in the comments.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Inconsistent behavior on java's ==
Integer wrapper objects share the same instances only within the value 127?
I have found the following == behaviour for Integer objects and I fail to understand it. (I am well aware that one should use equals for such comparisons, but I am studying for OCPJP...)
On short, == works as expected for 1000, but not for 10.
The former fragment of code is:
Integer i1 = 1000;
Integer i2 = 1000;
if(i1 != i2) System.out.println("different objects");
if(i1.equals(i2)) System.out.println("meaningfully equal");
and it behaves as one would expect:
different objects
meaningfully equal
The latter though:
Integer i3 = 10;
Integer i4 = 10;
if(i3 == i4) System.out.println("same object");
if(i3.equals(i4)) System.out.println("meaningfully equal");
has the following output:
same object
meaningfully equal
Can someone please explain why this is happening?
Since Java 5, wrapper class caching was introduced. The following is an examination of the cache created by an inner class, IntegerCache, located in the Integer cache. For example, the following code will create a cache:
Integer myNumber = 10
or
Integer myNumber = Integer.valueOf(10);
256 Integer objects are created in the range of -128 to 127 which are all stored in an Integer array. This caching functionality can be seen by looking at the inner class, IntegerCache, which is found in Integer:
So when creating an object using Integer.valueOf or directly assigning a value to an Integer within the range of -128 to 127 the same object will be returned. Therefore, consider the following example:
Integer i = 100;
Integer p = 100;
if (i == p)
System.out.println("i and p are the same.");
if (i != p)
System.out.println("i and p are different.");
if(i.equals(p))
System.out.println("i and p contain the same value.");
The output is:
i and p are the same.
i and p contain the same value.
It is important to note that object i and p only equate to true because they are the same object, the comparison is not based on the value, it is based on object equality. If Integer i and p are outside the range of -128 or 127 the cache is not used, therefore new objects are created. When doing a comparison for value always use the “.equals” method. It is also important to note that instantiating an Integer does not create this caching.
Remember that “==” is always used for object equality, it has not been overloaded for comparing unboxed values
See Integer wrapper objects share the same instances only within the value 127?. The Integer class keeps shared static instances around for common values.
I use code like:
Double getabsValue(final Object[] value){
if (value==null) return null;
if (value.lengt==0) return null;
final Double absValue=Maths.abs(value[0]);
if (absValue>0) return absValue
else return null;
But in my application I have problem with performance.
How it can be optimized?
Maybe better use?
if (absValue>0) return absValue
else return absValue<0?-absValue:null;
Thanks
Well, the code you've got at the moment won't even compile - there's no Math.abs(Object) call as far as I'm aware. However, assuming you actually have a cast to Double there, you're going to be boxing all the time. You could avoid boxing when the value is already greater than 0, and avoid the call when the value is 0, like this:
static Double getAbsValue(Object[] values) {
if (values == null || values.length == 0) {
return null;
}
Double value = (Double) values[0];
return value > 0 ? value
: value == 0 ? null
: -value;
}
By the time we get to the final option, we already know that the value is negative, so we don't really need the call to abs any more.
It's not really clear what the context is here. You say you've got a performance problem, but is it definitely in this code?
EDIT: Your latest code shows:
if (absValue>0) return absValue
else return -1*absValue;
That doesn't do the same thing - it doesn't return null if the array contains a boxed 0 value, as your original code does.
You should focus on correctness before performance.
What do you want your code to do with an input of 0? If you want it to return 0, then I would use:
return value >= 0 ? value : -value;
If you want it to return null, use the code I provided originally.
Why include a multiplication by -1 rather than just use the unary negation operator, by the way? I would expect either the compiler or the JIT to get rid of that anyway, but fundamentally you don't want to be performing multiplication - you want to perform negation. Make your code read as closely as possible to how you'd describe your aims.
I use code like:
Double getabsValue(final Object[] value){
Why?
The first thing I would do with this is redefine the signature.
It is pointless to specify Object[] when it basically has to be a Double[], or at least an Object[] which contains Doubles, otherwise it will throw a ClassCastException.
Why specify an array when you only use the first element?
Why a Double when what you really need is a double?
So I would redefine it it to take a single argument of type double. That moves the overhead of getting things out of the array back to the caller where he can see it. He may not even have an array, so he would have to construct it to call this method. And he may already have a double not a Double, in which case again he or the compiler would have to box it into a Double.
The second thing I would do with it is review what's left after this change. The change gets rid of the null and length checks, and the typecast, so all you are left with is return Math.abs(d); So it becomes clear that the entire method is basically pointless.
So the third thing I would do with it is delete it.
I'm a bit confused about the way Java treats == and equals() when it comes to int, Integer and other types of numbers. For example:
Integer X = 9000;
int x = 9000;
Short Y = 9000;
short y = 9000;
List<Boolean> results = new ArrayList<Boolean>();
// results.add(X == Y); DOES NOT COMPILE 1)
results.add(Y == 9000); // 2)
results.add(X == y); // 3)
results.add(X.equals(x)); // 4)
results.add(X.equals(Y)); // 5)
results.add(X.equals(y)); // 6)
System.out.println(results);
outputs (maybe you should make your guess first):
[true, true, true, false, false]
That X == Y does not compile is to be expected, being different objects.
I'm a little surprised that Y == 9 is true, given that 9 is by default an int, and given that 1) didn't even compile. Note that you can't put an int into a method expecting a Short, yet here they are equal.
This is surprising for the same reason as two, but it seems worse.
Not surprising, as x is autoboxed to and Integer.
Not surprising, as objects in different classes should not be equal().
What?? X == y is true but X.equals(y) is false? Shouldn't == always be stricter than equals()?
I'd appreciate it if anyone can help me make sense of this. For what reason do == and equals() behave this way?
Edit: I have changed 9 to 9000 to show that this behavior is not related to the any unusual ways that the integers from -128 to 127 behave.
2nd Edit: OK, if you think you understand this stuff, you should consider the following, just to make sure:
Integer X = 9000;
Integer Z = 9000;
short y = 9000;
List<Boolean> results = new ArrayList<Boolean>();
results.add(X == Z); // 1)
results.add(X == y); // 2)
results.add(X.equals(Z)); // 3)
results.add(X.equals(y)); // 4)
System.out.println(results);
outputs:
[false, true, true, false]
The reason, as best as I understand it:
Different instance, so different.
X unboxed, then same value, so equal.
Same value, so equal.
y cannot be boxed to an Integer so cannot be equal.
(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.
The morale of the story:
Autoboxing/unboxing is confusing, as is type promotion. Together, they make for good riddles but horrendous code.
In practice, it seldom makes sense to use numeric types smaller than int, and I'm almost inclined to configure my eclipse compiler to flag all autoboxing and -unboxing as an error.
Your problem here is not only how it treats == but autoboxing... When you compare Y and 9 you are comparing two primitives that are equal, in the last two cases you get false simply because that's how equals work. Two objects are equal only if they are of the same kind and have the same value.
When you say in "X.equals(y)" you are telling it to do Integer.equals(Short) and looking at the implementation of Integer.equals() it will fail:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
Because of autoboxing the last two will result in the same failure as they will both be passed in as Shorts.
Edit: Forgot one thing... In the case of results.add(X == y); it will unbox X and do (X.intValue() == y) which happens to be true as well as 9 == 9
This automatic conversion is called autoboxing.
I remember a good practice for overriding "equal(object obj)" is of first checking the type of the parameter passed in. So perhap this causes X.equals(Y) to be false. You might check the souce code to dig out the truth :)
A bit more detail on how autoboxing works and how "small" valued Integer objects are cached:
When a primitive int is autoboxed into an Integer, the compiler does that by replacing the code with a call to Integer.valueOf(...). So, the following:
Integer a = 10;
is replaced by the compiler with the following:
Integer a = Integer.valueOf(10);
The valueOf(...) method of class Integer maintains a cache that contains Integer objects for all values between -127 and 128. If you call valueOf(...) with a value that's in this range, the method returns a pre-existing object from the cache. If the value is outside the range, it returns a new Integer object initialized with the specified value. (If you want to know exactly how it works, lookup the file src.zip in your JDK installation directory, and look for the source code of class java.lang.Integer in it.)
Now, if you do this:
Integer a = 10;
Integer b = 10;
System.out.println(a == b);
you'll see that true is printed - but not because a and b have the same value, but because a and b are referring to the same Integer object, the object from the cache returned by Integer.valueOf(...).
If you change the values:
Integer a = 200;
Integer b = 200;
System.out.println(a == b);
then false is printed, because 200 is outside the range of the cache, and so a and b refer to two distinct Integer objects.
It's unfortunate that == is used for object equality for value types such as the wrapper classes and String in Java - it's counter-intuitive.
Java will convert an Integer into an int automatically, if needed. Same applies to Short. This feature is called autoboxing and autounboxing. You can read about it here.
It means that when you run the code:
int a = 5;
Integer b = a;
System.out.println(a == b);
Java converts it into:
int a = 5;
Integer b = new Integer(a);
System.out.println(a == b.valueOf());