Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method invokes inefficient new Integer(int) constructor; use Integer.valueOf(int) instead

My aim is to optimize my application code. My code looks like this:

int a = 10;
Map<String , Integer> myMap = new TreeMap<>();

myMap.put("first" , new Integer(a)); //[FindBugs] Method com.abc.xyz.Test.main(String[]) invokes inefficient new Integer(int) constructor; use Integer.valueOf(int) instead 

When i did static analysis by Findbugs in Netbeans, it shows that there is a warning/bug like "Method invokes inefficient new Integer(int) constructor; use Integer.valueOf(int) instead".

I know the difference between new Integer(int) vs Integer.valueOf(int).

One creates an additional object and the other do not. Also one does not caching and the other caches.

So i have modified my code like this...

m.put("first" , Integer.valueOf(a)); // Unnecessary boxing to Integer

but again that also gives warning "Unnecessary boxing to Integer" (by editor not by findbugs).

So, i have changed it again as like this....

m.put("first" , a); //No warning at all...

which finally gives no warning at all.

My Question:

1.) This link suggest that internally(by compiler) m.put("first" , a); is converting in m.put("first" , Integer.valueOf(a));

(On that example, there is a List-ArrayList and here we have Map-TreeMap...FYI). then why editor gives warning? And what should i do? what is the optimized way?

2.) If instead of Map, if there is any data structure like HashTable then ???

3.) Why editor gives Unnecessary boxing to Integer.

4.) Why m.put("first" , a) works? Because i am passing primitive variable and map's put() only accept Object. So is it because of auto boxing?

like image 394
Manan Shah Avatar asked Aug 28 '14 09:08

Manan Shah


People also ask

What is new integer in Java?

Integer class is a wrapper class for the primitive type int which contains several methods to effectively deal with an int value like converting it to a string representation, and vice-versa.

Is integer deprecated?

Deprecated. It is rarely appropriate to use this constructor.


2 Answers

1.) This link suggest that internally(by compiler) m.put("first" , a); is converting in m.put("first" , Integer.valueOf(a));

(On that example, there is a List-ArrayList and here we have Map-TreeMap...FYI). then why editor gives warning? And what should i do? what is the optimized way?

Yes, the compiler knows that m.put("first", a) only accepts objects and thus applies autoboxing. In terms of performance, using autoboxing or writing Integer.valueOf(a) would not make any difference.

On the other hand, new Integer(a) is not really slower than Integer.valueOf(a). The difference is that for small absolute values (default would be -128 to 127) Integer.valueOf(a) will use a cache, i.e. won't create new objects all the time. For all other values it will invoke new Integer(a) anyways.

Example:

Integer.valueOf(1) == Integer.valueOf(1) will yield true
Integer.valueOf(1000) == Integer.valueOf(1000) will yield false
new Integer(1) == new Integer(1) will yield false, as the cache is not used here

2.) If instead of Map, if there is any data structure like HashTable then ???

Why are you asking that? There is HashTable but since it is synchronized it means more overhead than HashMap, so unless you need synchronization stick to HashMap or TreeMap if you need sorting.

3.) Why editor gives Unnecessary boxing to Integer.

It's probably just because of readability (a is shorter than Integer.valueOf(a)).

4.) Why m.put("first" , a) works? Because i am passing primitive variable and map's put() only accept Object. So is it because of auto boxing?

See 1

like image 178
Thomas Avatar answered Sep 22 '22 04:09

Thomas


4.) Why m.put("first" , a) works? Because i am passing primitive variable and map's put() only accept Object.

Autoboxing.

int are automatically converted into Integer and vice-versa (with possible NullPointerException in this case)

3.) Why editor gives Unnecessary boxing to Integer.

Because you don't need to write this piece of code. The compiler will do it for you.

It is usually more readable

2.) If instead of Map, if there is any data structure like HashTable, then case is same???

Yes in JDK collections only work with Objects. It means that primitive types must be boxed. It has a small runtime cost and a huge memory overhead. An Integer take ~300% more memory than an int.

You cannot escape it. The only way to avoid the boxing overhead is to use specialized collections like GNU trove which provide one class per primitive type. Only useful if you plan to store millions of primitive elements into a collection.

And finally never ever write new Integer(x). Integer.valueOf(x) does the same thing but it maintains an internal cache to avoid creating new instances for some commonly used values.

like image 38
Clément MATHIEU Avatar answered Sep 22 '22 04:09

Clément MATHIEU