Reputation: 2123
Let's say I want to create an ArrayList
for numbers. The way I learned it is like this:
private static List<Integer> numbers = new ArrayList<Integer>();
But IntelliJ IDEA wants to correct it to
private static List<Integer> numbers = new ArrayList<>();
And then I found out this works as well:
private static List<Integer> numbers = new ArrayList();
Now I'm confused, what's the best way? And what's the difference. Same question applies to HashMap
.
Upvotes: 3
Views: 1073
Reputation: 9541
The best way is:
private static List<Integer> numbers = new ArrayList<>(); // Java 7
private static List<Integer> numbers = new ArrayList<Integer>(); // Java 6
Lets take a look at the other examples:
private static ArrayList<Integer> numbers = new ArrayList<Integer>();
uses a specific class as the type, which is discouraged unless you need to access ArrayList-specific methods (I don't know any)
private static ArrayList<Integer> numbers = new ArrayList();
is type-unsafe, and your IDE should give you a warning on this line.
Upvotes: 7
Reputation: 678
All the examples given will compile to the same bytecode, and do not affect subsequent type checks. The reason for using one or another is avoiding annoying warnings.
new ArrayList();
is the pre-generics way. The compiler will warn you because you are not caring about generics (and potentially assigning an ArrayList
with elements other than Integer
).new ArrayList<Integer>();
is the generics-way, but before the compiler was smart enough to infer itself the element type. Therefore it warns you because it is more verbose than necessary.new ArrayList<>();
is the currently preferred way (thanks to Type Inference introduced in Java 7 (see related SO question) ). Go for it unless you have to deal with older compilers.Maybe an interesting question would be why new ArrayList<>();
is best (type inference) but new ArrayList();
is not.
Upvotes: 2
Reputation: 1131
The first example is correct, you supply everything needed. But it also means you repeat the definition of the parameter type.
Then, in Java 1.7 (or maybe 1.8, not quite sure) they introduced the shortened version - so in case you define ArrayList<Integer> numbers
, there is no need to define repeat that ArrayList
for Integer
should be created and you just keep <>
there. This is sometimes called a diamond notation and instructs compiler to use the very same data type that you used for the field definition. So, as a result it behaves exactly like the first example, but without the need to duplicate the information about data type.
The last case you have there is somewhat different as you create an ArrayList
of no specified data type. This can be somewhat dangerous as it allows you to write the following code:
List listAnything = new ArrayList();
listAnything.add("string");
listAnything.add(42);
listAnything.add(false);
List<Integer> listInteger = listAnything;
The above listed code compiles perfectly fine, though there are some warnings about unchecked conversions and using raw types. You are no longer to guarantee that listInteger
contains only integers.
Also, word of warning here - you should rely on abstraction as much as possible in your code. By this I mean to define your fields using an interface or an abstract class rather than concrete one. Such a code is a significantly better to read and to maintain:
ArrayList<Integer> list = new ArrayList<>(); // this is not wrong...
List<Integer> list = new ArrayList<>(); // ...but this is better
Upvotes: 1
Reputation:
You should be using the interface in the left side:
private static List<Integer> numbers = new ArrayList<>();
Unless you really need any of the specific methods for that data structure.
IntelliJ IDEA is suggesting you that construct since you are using the JDK 1.7.x (or superior) and there is no need to specify again the type because the compiler can infer the type arguments from the context (again from Java 7 and/or later).
Upvotes: 3