Showing posts with label Integer. Show all posts
Showing posts with label Integer. Show all posts

Thursday, November 28, 2013

Integer constant pool in java

In this post, we'll look into Integer Wrapper class and its Integer constant pool concept with reason behind it for creating such pool with few examples.

What is Integer Class?
The Integer class wraps a value of the primitive type int in an object. An object of type Integer contains a single field whose type is int.

In addition, this class provides several methods for converting an int to a String and a String to an int, as well as other constants and methods useful when dealing with an int.

Before moving further please guess the output of the following program. If you are able to answer them all correct, then it's means you know how Java Integer Constant pool works :)

You can find the answer at the bottom of the post. If your answers are not right, then read further to know why Integer class behave in a unusual way.

Integer i = 10 vs Integer j = new Integer(10)
After compiling this class, I tried to de-compile the same class. What is got it this
So java called Integer.valueOf() whenever we create object of Integer class as Integer i = 10;

Integer.valueOf()
Let's see what does this function do. As per the Oracle doc, it says 
public static Integer valueOf(int i)
Returns an Integer instance representing the specified int value. 

If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.

To explore further, let's have a look at the code of Integer.valueOf() function 

It's clear from the above code that when we call valueof() function with value range from -128 to 127, it always cache the value.



Integer.cache is the class that help us in caching in Integer values. The size of the cache may be controlled by the 
-XX:AutoBoxCacheMax= <size>
Or this can achieved with system property
-Djava.lang.Integer.IntegerCache.high=<size>

In other words, when we create object of Integer class 
Integer i = 10;
Integer j = new Integer(10); 
both refer to the same instance in the pool.
So you get the same reference if value is between -128 to 127 and you call valueOf() else it just returns new Integer(int). As reference is same your == operator works for integer returned by valueOf() between this range.

Java caches the integer objects in the range -128 to 127. So, when you try to assign a value in this range to a wrapper object, the boxing operation will invoke Integer.valueOf() method and in turn it will assign a reference to the object already in the pool.
On the other hand, if you assign a value outside this range to a wrapper reference type, Integer.valueOf will create a new Integer object for that value. And hence, comparing the reference for Integer objects having value outside this range will give you false.

I hope at this point, you got the idea of Integer Constant pool. So have a look at the above code for which you have to guess the output and see this time, will you able to answer all the question correct.

Summary of Integer constant pool


Answers
IntegerClassExampleOne 
i==j is not equal

IntegerClassExampleTwo
i==j is not equal

IntegerClassExampleThree
i==j is not equal

IntegerClassExampleFour
i==j is equal



If you know anyone who has started learning java, why not help them out! Just share this post with them. Thanks for studying today!...

Thursday, August 22, 2013

Why we need Wrapper classes in Java

The wrapper classes in the Java API serve two primary purposes : To provide a mechanism to "wrap" primitive values in an object so that the primitives can be included in activities reserved for objects and to provide an assortment of utility functions for primitives. In this post, we'll see what are wrapper classes, why we need them, how it differ from primitive data types and why we need them in Collection frameworks.
What is wrapper class
From the image, it's easily to get what is a wrapper and how it will going to relate wrapper classes in java.
In general, a wrapper class is any class which "wraps" or "encapsulates" the functionality of another class or component. These are useful by providing a level of abstraction from the implementation of the underlying class or component.
Each of Java's eight primitive data types has a class dedicated to it. These are known as wrapper classes, because they "wrap" the primitive data type into an object of that class. 
So, there is an Integer class that holds an int variable, there is a Double class that holds a double variable, and so on for byte, short, int, long, float, double, boolean, & char.

How wrapper class differ from primitive datatypes?

For instance,
int x = 25;
Integer y = new Integer(33);

The first statement declares an int variable named x and initializes it with the value 25. The second statement instantiates an Integer object. The object is initialized with the value 33 and a reference to the object is assigned to the object variable y. See the memory assignment in the following image.



Clearly x and y differ by more than their values: x is a variable that holds a value; y is an object variable that holds a reference to an object.

So data fields in objects are not, in general, directly accessible. So, the following statement using x and y as declared above is not allowed
int z = x + y; // wron

The data field in an Integer object is only accessible using the methods of the Integer class. One such method — the intValue() method — returns an int equal to the value of the object, effectively "unwrapping" the Integer object

int z = x + y.intValue(); // OK


How object (wrapper) have more overhead than their primitive counterparts?

We see this with the help of an example:
we first put a number of primitive values into an collection and an array. Then we do an arithmetic operation on each value of the collection or array. The array loop performs much better than the collection loop, since collections need to perform boxing conversions before doing arithmetic multiplication on their contents. 
import java.util.*;
public class AutoBoxingPerformanceTest{
    public static void main(String args[]){
        long time1 = 0;
        long time2 = 0;
        List listValues = new ArrayList();
        int arrValues[] = new int[1000000];
        /* Inserting values into List and Array */
        for(int i =0;i<1000000;i++){
            listValues.add(i);
            arrValues[i]=i;
        }
        /* Reterive the values from collection objects and do the multiplication*/
        time1 = System.currentTimeMillis();
        for(int i=0;i<1000000;i++){
            listValues.set(i,listValues.get(i)*10);
        }
        time2 = System.currentTimeMillis();
        System.out.println("AutoBoxing with Collection : "+(time2-time1)+"ms");
        /* Reterive the values from arrays and do the multiplication*/
        time1 = System.currentTimeMillis();
        for(int i=0;i<1000000;i++){
            arrValues[i]=arrValues[i]*10;
        }
        time2 = System.currentTimeMillis();
        System.out.println("Using an Array : "+(time2-time1)+"ms");
    }
}

Output :

AutoBoxing with Collection : 421ms
Using an Array : 0ms

So we have to be aware when we may be doing unnecessary things that could impact performance, such as autoboxing when we should not.


Why we need wrapper classes

  1. So that we can include wrapper classes in Collection.
  2. Null value is possible with wrapper classes.
  3. It can be handy to initalise Object with null or send null parameters to a method or constructor to indicate state or function. This can't be possible with primitives.
  4. We can treat wrapper classes generically / polymorphically as an object along with other objects.
  5. Sometime we initalise numbers to 0(default) or -1, depending on the scenario this may be incorrect or misleading to confusion.
  6. With wrapper we could get NullPointerException when something is being set incorrectly, which is more programmer friendly than some arbitrary bug down the line.
  7. *To get type safety we use generics and generics need objects not primitives.

What are disadvantage of Wrapper classes
As we have already seen the performance comparison of Wrapper over primitive counterparts.
  1. Primitive datatypes may be a lot faster than their corresponding wrapper types i,.e wrapper classes may perform slow.
  2. There can some unexpected behavior involving
    == comparing references
    .equal()  comparing values

To prove above 2nd point, please run the following code
public class AutoBoxingTest{
    public static void main(String args[]){
        Integer iVar1 = new Integer(10);
        Integer iVar2 = 10;
        System.out.println("Lessthan Check : " + (iVar1 <= iVar2));
        System.out.println("Greater than Check : " + (iVar1 >= iVar2));
        System.out.println("Equality Check : " + (iVar1 == iVar2));
    }
}

How to choose between wrapper and primitive datatypes

  • Generally, you should use primitive types unless you need an object for some reason (e.g. to put in a collection)
  • There are certain constructs such as Collections require objects, and that objects have more overhead than their primitive counterparts as we seen above in term of memory and autoboxing.
  • If you still need wrapper, consider a different approach  that doesn't require object if you want to maximize the numeric datatype performance.
  • We also must consider that autoboxing i.e wrapper class doesn't reduce object creation, but it reduce code complexity.

Another question come into picture that we can store primitive directly in Collection. How come?
For instance,
List<Integer> list = new ArrayList<>();
list.add(1);
int i = list.get(0);

Java Collection can only store object references i.e, Collection store their values via references to an object memory location in the heap. 

As local variable are stored on stack, while storing primitive in collection, collection get the reference for a primitive data with the help of autoboxing i.e,it take the value from stack and wrap it for storage on heap.

If you see the add() method definition of Array List, it's look like this add(E e)

Above code is automatically converted into the following
List.add(Integer.valueOf(7));

Conclusion :
It's not recommended to use wrapper for scientific calculation. For instance, the code
d =  a * b + c ; 

is using Integer classes for a,b,c,& d and generate code will be look like 
d.valueOf(a.intValue() * b.intValue() + c.intValue())
All these method have there own overhead over primitive datatypes.
So, it is recommended to use wrapper when need to store primitive in Collection

Even, If you have huge collection of wrapper class like Integer wrapping int, the overhead can imply longer execution time as stated above.

Java designers kept the two separate to keep things simple. You use the wrappers when you need types that fit in the object oriented world - like polymorphism, collections etc.
You use the primitives when you need efficiency.


If you know anyone who has started learning Java, why not help them out! Just share this post with them. Thanks for studying today!...