0

Let's assume there is a code that's supposed to add primitives to Collection:

List<Integer> list = new ArrayList<>();

I'm curios which variant will be faster and why?

  1. Variant1:

    list.add(1);
    list.add(2);
    ...
    list.add(n);
    
  2. Variant2:

    list.add(new Integer(1));
    list.add(new Integer(2));
    ...
    list.add(new Integer(n));
    
  3. Variant3:

    list.add(Integer.valueOf(1));
    list.add(Integer.valueOf(2));
    ...
    list.add(Integer.valueOf(n));
    

My assumption that Variant1 will be faster but I have no proves.

user2738882
  • 1,161
  • 1
  • 20
  • 38
  • 1
    There is rarely ever a valid reason to use the constructor, it bypasses the internal cache. The first and last version are equivalent. The compiler translates both to the same bytecode. If your question is about speed, there is no way around actually measuring it with JMH. Everything else is just "educated guessing" which is wrong more often than right. So my guess is clearly 1 and 3 are faster since cache and also fastest since equivalent. – Zabuzard Dec 26 '19 at 12:36
  • run a benchmark test and find it yourself. I believe option 1 is better and seems of less entropy. – Vishwa Ratna Dec 26 '19 at 12:37
  • 2
    2nd is the least efficient one since you recreate even the cached integers between -128 and 127. The other two are probably the same. – luk2302 Dec 26 '19 at 12:38
  • In your case I think you can use `IntStream.rangeClosed(1, n).boxed().collect(Collectors.toList());` – Youcef LAIDANI Dec 26 '19 at 12:38
  • @YCF_L , you are anyways doing boxing. – Vishwa Ratna Dec 26 '19 at 12:39
  • If your list is large you might also want to take into consideration a parallelized stream-variant, might be faster after a certain size. `IntStream.rangeClosed(1, n).boxed().collect(Collectors.toList())`. Most likely slightly slower if below the threshold size. – Zabuzard Dec 26 '19 at 12:40
  • 1
    @VishwaRatna But it _could_ be done in-parallel which could potentially speed up things in certain situations. – Zabuzard Dec 26 '19 at 12:41
  • Why not then `Arrays.asList(1,2,3)` – Vishwa Ratna Dec 26 '19 at 12:42
  • 1
    What is the point of this question? Just a search of "Different ways of adding Integer to list in Java" can give you pros and cons of each. – Vishwa Ratna Dec 26 '19 at 12:45
  • 2
    @YCF_L `Arrays.asList` is **not** immutable, it is just fixed length. You can't remove items or add items, but you can **replace** items by index. – Mark Rotteveel Dec 26 '19 at 15:15
  • 1
    Related: [Differences between new Integer(123), Integer.valueOf(123) and just 123](https://stackoverflow.com/questions/9030817/differences-between-new-integer123-integer-valueof123-and-just-123) – Mark Rotteveel Dec 26 '19 at 15:18

1 Answers1

-2

The answer to this question can be opinion based. That means there can be positives as well as negatives for the answers. Variant1 will be better in my opinion. It's the same thing with less code.

Unless I expect that the program would have to run on an older version of JVM. However, in that case this would be far from being the only compatibility issue.

So, the only reason not to use autoboxing is if it's not available.

Autoboxing does create objects which are not clearly visible in the code. So when autoboxing occurs performance suffers.

It is not appropriate to use autoboxing and unboxing for scientific computing, or other performance-sensitive numerical code. An Integer is not a substitute for an int; autoboxing and unboxing blur the distinction between primitive types and reference types, but they do not eliminate it.

Confused Equals
Autoboxing has brought with itself a lot of things that just are not obvious to a programmer. What would be the output of below code?

Long longWrapperVariable=2L ;
System.out.println(longWrapperVariable.equals(2));
System.out.println(longWrapperVariable.equals(2L));

Here is what the above code prints:

false
true

If you are wondering what happened above, 2 was boxed to Integer and hence equals could not compare it with Long. And 2L was boxed to Long and hence returned true.

OutOfMemoryError
A boxing conversion may result in an OutOfMemoryError if a new instance of one of the wrapper classes (Boolean, Byte, Character, Short, Integer, Long, Float, or Double) needs to be allocated and insufficient storage is available.

More reference: https://dzone.com/articles/autoboxing-and-its-pitfalls-1

Nivin John
  • 173
  • 1
  • 11
  • Why is this post given negative reputation? – Nivin John Dec 27 '19 at 06:50
  • Because this is something that can be quantified through benchmarking, not opinions. As for the "comparing longs", `Integer != Long` isn't exactly groundbreaking news. Not sure what this answer is providing in terms of the question that was asked. – Vince Aug 07 '22 at 13:32