Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Wiki Markup
This noncompliant code example (adopted from \[[Bloch 09|AA. Java References#Bloch 09]\]), defines a {{Comparator}} with a {{compare()}} method. The {{compare()}} method accepts two boxed primitives as arguments. Note that primitive integers are also accepted by this declaration as they are appropriately autoboxed. The main issue is that the {{==}} operator is being used to compare the two boxed primitives. ThisHowever, however,this compares their references and not the actual values. 

...

To be compliant, use any of the four comparison operators <, >, <= and >=. The == and != operators should not be used to compare boxed primitives.

...

Code Block
bgColor#FFCCCC
public class TestWrapper2 {
 public static void main(String[] args) {
 
  Integer i1 = 100;
  Integer i2 = 100;
  Integer i3 = 1000;
  Integer i4 = 1000;
  System.out.println(i1 == i2);
  System.out.println(i1 != i2);
  System.out.println(i3 == i4);
  System.out.println(i3 != i4);
 
 }
}

These comparisons generate the output sequence: true, false, false and true. The cache in the Integer class can only make the integers from -127 to 128 refer to the same object, which explains the output of the above code. To avoid making such mistakes, use the equals() method instead of == to compare wrapper classes (See EXP03-J for further details).

...

Using object1.equals(object2) only compares their the values of the objects. Now, the results will be true, as expected.

...

Sometimes a list of integers is desired. Recall that the type parameter inside the angle brackets of a list cannot be of a primitive type. It is not possible to form an ArrayList<int> that contains values of type int. With the help of the wrapper classs classes and autoboxing, storing primitive it becomes possible to store integer values in an ArrayList<Integer> becomes possible instance.

In this noncompliant code example, it is desired to count the integers of arrays list1 and list2. As class Integer only caches integers from -127 to 128, when an int value is beyond this range, it is autoboxed into the corresponding wrapper type. The == operator returns false when these distinct wrapper objects are compared. As a result, the output of this example is 0.

Code Block
bgColor#FFCCCC
public class Wrapper {
 public static void main(String[] args) {
   // Create an array list of integers, where each element 
   // is greater than 127
   ArrayList<Integer> list1 = new ArrayList<Integer>();
  
   for(int i = 0;i<10; i < 10; i++) {
     list1.add(i + 1000);
   }

   // Create another array list of integers, where each element
   // is the same as the first list
   ArrayList<Integer> list2 = new ArrayList<Integer>();
   
   for(int i = 0;i<10; i < 10; i++) {
     list2.add(i + 1000);
   }
 
   int counter = 0;
   for(int i = 0;i<10; i < 10; i++) {
     if(list1.get(i) == list2.get(i)) { 
       counter++;
     }
   }

   // print the counter
   System.out.println(counter);
 }
}

If it were possible to expand the Integer cache (for example, caching all the values -32K – 32K32768 to 32767, which means that all the int values in the example would be autoboxed to cached Integer objects), then the results may have differed.

...

Code Block
bgColor#CCCCFF
public class TestWrapper1 {
 public static void main(String[] args) {
   // Create an array list of integers, where each element
   // is greater than 127
   ArrayList<Integer> list1 = new ArrayList<Integer>();

   for(int i = 0;i<10; i < 10; i++) {
     list1.add(i+1000);
   }

   // Create another array list of integers, where each element
   // is the same as the first one
   ArrayList<Integer> list2 = new ArrayList<Integer>();
   for(int i=0;i<10;i++) {
     list2.add(i+1000);
   }
 
   int counter = 0;

   for(int i=0;i<10;i++) {
     if(list1.get(i).equals(list2.get(i))) { 
       counter++;
     }
   }
 
   System.out.println(counter);
 }
}

...