27

I'm a newbie Java coder and I just read a variable of an integer class can be described three different ways in the API. I have the following code:

if (count.compareTo(0)) { 
            System.out.println(out_table);
            count++;
    }

This is inside a loop and just outputs out_table.
My goal is to figure out how to see if the value in integer count > 0.

I realize the count.compare(0) is the correct way? or is it count.equals(0)?

I know the count == 0 is incorrect. Is this right? Is there a value comparison operator where its just count=0?

towi
  • 21,587
  • 28
  • 106
  • 187
phill
  • 13,434
  • 38
  • 105
  • 141

7 Answers7

31

To figure out if an Integer is greater than 0, you can:

  • check if compareTo(O) returns a positive number:

    if (count.compareTo(0) > 0)
         ...
    

    But that looks pretty silly, doesn't it? Better just...

  • use autoboxing1:

    if (count > 0)
        ....
    

    This is equivalent to:

    if (count.intValue() > 0)
        ...
    

    It is important to note that "==" is evaluated like this, with the Integer operand unboxed rather than the int operand boxed. Otherwise, count == 0 would return false when count was initialized as new Integer(0) (because "==" tests for reference equality).

1Technically, the first example uses autoboxing (before Java 1.5 you couldn't pass an int to compareTo) and the second example uses unboxing. The combined feature is often simply called "autoboxing" for short, which is often then extended into calling both types of conversions "autoboxing". I apologize for my lax usage of terminology.

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
  • 1
    The former example is using autoboxing; the latter autounboxing. – Tom Hawtin - tackline Jun 04 '09 at 21:33
  • 4
    +1: Regarding the `==` comparison, one should be very cautious when comparing *two* *boxed* numbers (but not one boxed and one primitive number), because, as mmyers mentioned, `==` tests for reference equality, not equality of the wrapped values. – Christian Semrau Apr 28 '10 at 14:48
27

Integers are autounboxed, so you can just do

if (count > 0) {
    .... 
}
Nathaniel Flath
  • 15,477
  • 19
  • 69
  • 94
  • 3
    Ummm. Not really. ... In other comparisons this is not always the case. What if you are comparing two Integers and using '=='? Then the instances are compared, but sometimes the JVM doesn't cache them so it reports identical values as different. See http://stackoverflow.com/questions/10002037/comparing-integer-values-in-java-strange-behavior . – ingyhere Dec 14 '13 at 19:41
  • @ingyhere Integer is autounboxed when comparing with int. – Alex78191 Nov 27 '19 at 12:38
  • @Alex78191: In the case of one boxed and one primitive comparison in this example it works, and the left-most value unboxes. This is not guaranteed for comparisons of two Integer objects, at least not in 2013 nor in all JVM implementations. That was the point, if I recall. Anyway, there's little cost to using `if (count.intValue() > 0) { ... }` as a practice except it may be beneficial to _limit_ autounboxing in loops. – ingyhere Nov 27 '19 at 15:24
13

It's better to avoid unnecessary autoboxing for 2 reasons.

For one thing, it's a bit slower than int < int, as you're (sometimes) creating an extra object;

void doSomethingWith(Integer integerObject){ ...
  int i = 1000;
  doSomethingWith(i);//gets compiled into doSomethingWith(Integer.valueOf(i));

The bigger issue is that hidden autoboxing can hide exceptions:

void doSomethingWith (Integer count){
  if (count>0)  // gets compiled into count.intValue()>0

Calling this method with null will throw a NullPointerException.

The split between primitives and wrapper objects in java was always described as a kludge for speed. Autoboxing almost hides this, but not quite - it's cleaner just to keep track of the type. So if you've got an Integer object, you can just call compare() or intValue(), and if you've got the primitive just check the value directly.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
Steve B.
  • 55,454
  • 12
  • 93
  • 132
  • +1 For mentioning the negative sides of autounboxing. The performance difference can be huge, especially when auto(un)boxing in loops. – helpermethod Feb 22 '10 at 00:52
13

You can also use equals:

 Integer a = 0;

 if (a.equals(0)) {
     // a == 0
 }

which is equivalent to:

 if (a.intValue() == 0) {
     // a == 0
 }

and also:

 if (a == 0) {

 }

(the Java compiler automatically adds intValue())

Note that autoboxing/autounboxing can introduce a significant overhead (especially inside loops).

Mo Beigi
  • 1,614
  • 4
  • 29
  • 50
dfa
  • 114,442
  • 31
  • 189
  • 228
3

Although you could certainly use the compareTo method on an Integer instance, it's not clear when reading the code, so you should probably avoid doing so.

Java allows you to use autoboxing (see http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html) to compare directly with an int, so you can do:

if (count > 0) { }

And the Integer instance count gets automatically converted to an int for the comparison.

If you're having trouble understanding this, check out the link above, or imagine it's doing this:

if (count.intValue() > 0) { }
jpdaigle
  • 1,265
  • 10
  • 12
  • up vote for informative links. Keep in mind that `count` has to be non-null. The Exception produced at runtime auto-unboxing a null value is confusing. – Chadwick Jun 04 '09 at 21:36
1

One more thing to watch out for is if the second value was another Integer object instead of a literal '0', the '==' operator compares the object pointers and will not auto-unbox.

ie:

Integer a = new Integer(0);   
Integer b = new Integer(0);   
int c = 0;

boolean isSame_EqOperator = (a==b); //false!
boolean isSame_EqMethod = (a.equals(b)); //true
boolean isSame_EqAutoUnbox = ((a==c) && (a.equals(c)); //also true, because of auto-unbox

//Note: for initializing a and b, the Integer constructor 
// is called explicitly to avoid integer object caching 
// for the purpose of the example.
// Calling it explicitly ensures each integer is created 
// as a separate object as intended.
// Edited in response to comment by @nolith
Sogger
  • 15,962
  • 6
  • 43
  • 40
  • You must instantiate `a` and `b` with `New Integer(0)` otherwise `isSame_EqOperator` will be `true` – nolith Dec 19 '12 at 16:10
  • Goodpoint @nolith, though this is due to caching of integers in Java, explained well in the accepted answer to http://stackoverflow.com/questions/3131136/integers-caching-in-java. I will change my answer to use your suggested edit with a comment describing why to explicitly use the constructor. – Sogger Dec 19 '12 at 22:13
-1

well i might be late on this but i would like to share something:

Given the input: System.out.println(isGreaterThanZero(-1));

public static boolean isGreaterThanZero(Integer value) {
    return value == null?false:value.compareTo(0) > 0;
}

Returns false

public static boolean isGreaterThanZero(Integer value) {
    return value == null?false:value.intValue() > 0;
}

Returns true So i think in yourcase 'compareTo' will be more accurate.