2014-08-28 43 views
5

我的目标是优化我的应用程序代码。我的代码如下所示:方法调用低效新的Integer(int)构造函数;使用Integer.valueOf(int)代替

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 

当我在Netbeans中做静态分析FindBugs的,它表明,有像“方法警告/错误将调用低效新的整数(int)构造;使用Integer.valueOf( int)而不是“。

我知道新的整数(INT) VS Integer.valueOf(INT)之间的差异。

一个创建另一个对象,另一个不创建。另外一个不缓存和其他缓存。

,所以我必须再次修改我的代码是这样的...

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

但也给了警告“不必要的拳击整数”(由编辑器不FindBugs的)。

所以,我又改变了它这样的....

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

其最后给出没有警告可言。

我的问题:

1)本link表明内部(由编译器)m.put( “第一”,一);正在转换m.put(“first”,Integer.valueOf(a));

(在这个例子中,有一个List-ArrayList,这里我们有Map-TreeMap ... FYI)。 那为什么编辑器会给出警告? 我该怎么办?优化的方式是什么?

2.)如果不是地图,如果有像的HashTable然后任何数据结构???

3.)为什么编辑给不必要的拳击Integer

4.)为什么m.put(“first”,a)有效?因为我通过原始变量和地图的put()只接受对象。那么是因为汽车拳击

+1

是的,它是由于自动装箱。 – 2014-08-28 09:50:35

+0

OK.thanks ...那么优化的好方法是什么?最后一个?? – 2014-08-28 09:53:50

+0

我不认为你可以优化它,自动装箱为你做同样的工作,所以你不需要显式地执行'valueOf(a)'。 – 2014-08-28 09:55:50

回答

4

1.)这个链接表明在内部(通过编译器)m.put(“first”,a);在m.put中转换(“first”,Integer.valueOf(a));

(在这个例子中,有一个List-ArrayList,这里我们有Map-TreeMap ... FYI)。那为什么编辑会给出警告?我该怎么办?优化的方式是什么?

是的,编译器知道m.put("first", a)只接受对象,因此应用自动装箱。在性能方面,使用自动装箱或写作Integer.valueOf(a)不会有任何区别。

另一方面,new Integer(a)并不比Integer.valueOf(a)慢。区别在于,对于小的绝对值(默认值为-128至127),Integer.valueOf(a)将使用缓存,即不会始终创建新对象。对于所有其他值,无论如何它都会调用new Integer(a)

例子:

Integer.valueOf(1) == Integer.valueOf(1)将产生真正的
Integer.valueOf(1000) == Integer.valueOf(1000)会产生错误的
new Integer(1) == new Integer(1)会产生错误的,作为缓存这里不

2.使用)如果相反的地图,如果有什么数据结构像HashTable那么?

你为什么这么问?有HashTable,但由于它是同步的,这意味着更多的开销比HashMap,所以除非你需要同步坚持HashMapTreeMap如果你需要排序。

3.)为什么编辑器给整数不必要的拳击。

这可能仅仅是因为可读性(a短于Integer.valueOf(a))。

4.)为什么m.put(“first”,a)有效?因为我传递原始变量和映射的put()只接受Object。那是因为汽车拳击吗?

见1

+0

谢谢托马斯......你清除了我的怀疑。我以为一样,但不知道这两者是否相同...是的,在我阅读过程中我得知约-128到127缓存范围... +1为平等的事情... – 2014-08-28 10:10:41

+0

所以我们不能盲目优化。 (更改为Integer.valueOf(int)可能会导致麻烦,如果某些参考比较或equals()进来的图片)正确? – 2014-08-28 10:13:26

+1

@MananShah是的,盲目优化几乎不是一个好主意。 :)'equals()'应该是一个问题,因为它应该总是产生相同的结果,但是对象相等(即==)可能是一个问题。通常使用==应谨慎使用,并且只有在需要_really_时才需要使用。 – Thomas 2014-08-28 10:49:40

1

4.)为什么m.put(“first”,a)有效?因为我传递原始变量和映射的put()只接受Object。

自动装箱。

INT被自动转换成整数,反之亦然(在这种情况下可能的NullPointerException)

3.)为什么编辑器提供了不必要的拳击整数。

因为你不需要写这段代码。编译器会为你做。

它通常是更易读

2.)如果不是地图,如果有像HashTable的任何数据结构,则壳体是相同???

是的,在JDK集合中只能使用对象。这意味着原始类型必须装箱。它具有很小的运行时间成本和巨大的内存开销。一个Integer需要比int更多300%的内存。

你不能逃避它。避免拳击开销的唯一方法是使用专门的集合,比如GNU trove,它为每个基本类型提供一个类。只有在计划将数百万原始元素存储到集合中时才有用。

终于永远不会写新的Integer(x)。 Integer.valueOf(x)做同样的事情,但它维护一个内部缓存,以避免为一些常用值创建新的实例。

+0

感谢您记住NullPointerException和代码可读性。我不知道GNU trove的东西......当然我会读它......我也不知道Integer = 300%int在内存方面.... :)很好。再次感谢。 – 2014-08-28 10:05:09

+0

由于问题1,我接受了托马斯的回答...对不起,我们只能接受一个答案。 – 2014-08-28 10:15:08

相关问题