[java] Adding values to Arraylist

Code 1:

ArrayList arr = new ArrayList();
arr.add(3);
arr.add("ss");

Code 2:

ArrayList<Object> arr = new ArrayList<Object>();
arr.add(3);
arr.add("ss");

Code 3:

ArrayList<Object> arr = new ArrayList<Object>();
arr.add(new Integer(3));
arr.add(new String("ss"));

all the above three codes are working fine.. can some one tell me the which is prefered and why.. and why the eclipse compiler always gives warning when type of arguments are not mentioned to the Arraylist.. thanks in advance..

This question is related to java

The answer is


Actually, a third is preferred:

ArrayList<Object> array = new ArrayList<Object>();
array.add(Integer.valueOf(3));
array.add("ss");

This avoids autoboxing (Integer.valueOf(3) versus 3) and doesn't create an unnecessary String object.

Eclipse complains when you don't use type arguments with a generic type like ArrayList, because you are using something called a raw type, which is discouraged. If a class is generic (that is, it has type parameters), then you should always use type arguments with that class.

Autoboxing, on the other hand, is a personal preference. Some people are okay with it, and some not. I don't like it, and I turn on the warning for autoboxing/autounboxing.


The second one would be preferred:

  • it avoids unnecessary/inefficient constructor calls
  • it makes you specify the element type for the list (if that is missing, you get a warning)

However, having two different types of object in the same list has a bit of a bad design smell. We need more context to speak on that.


Two last variants are the same, int is wrapped to Integer automatically where you need an Object. If you not write any class in <> it will be Object by default. So there is no difference, but it will be better to understanding if you write Object.


in the first you don't define the type that will be held and linked within your arraylist construct

this is the preferred method to do so, you define the type of list and the ide will handle the rest

in the third one you will better just define List for shorter code


The second form is preferred:

ArrayList<Object> arr = new ArrayList<Object>();
arr.add(3);
arr.add("ss");

Always specify generic arguments when using generic types (such as ArrayList<T>). This rules out the first form.

As to the last form, it is more verbose and does extra work for no benefit.


There's a faster and easy way in Java 9 without involving much of code: Using Collection Factory methods:

List<String> list = List.of("first", "second", "third");

Well by doing the above you open yourself to run time errors, unless you are happy to accept that your arraylists can contains both strings and integers and elephants.

Eclipse returns an error because it does not want you to be unaware of the fact that by specifying no type for the generic parameter you are opening yourself up for run time errors. At least with the other two examples you know that you can have objects in your Arraylist and since Inetegers and Strings are both objects Eclipse doesn't warn you.

Either code 2 or 3 are ok. But if you know you will have either only ints or only strings in your arraylist then I would do

ArrayList<Integer> arr = new ArrayList<Integer>();

or

ArrayList<String> arr = new ArrayList<String>();

respectively.


You are getting the warning because ArrayList is part of java generics. Essentially, it's a way to catch your type errors at compile time. For example, if you declare your array list with types Integer (ArrrayList<Integer>) and then try to add Strings to it, you'll get an error at compile time - avoiding nasty crashes at runtime.

The first syntax is there for backward compatibility and should be avoided whenever possible (note that generics were not there in older versions of java).

Second and third examples are pretty much equivalent. As you need to pass an object and not a primitive type to add method, your 3 is internally converted to Integer(3). By writing a string in double-quotes you effectively are creating a String object. When calling String("ss") you are creating a new String object with value being the same as the parameter ("ss").

Unless you really do need to store different types in your List, I would suggest actually using a proper type declaration, e.g. ArrayList<Integer> = new ArrayList<Integer>() - it'll save you a lot of headache in the long run.

If you do need multiple datatypes in the list, then the second example is better.