There is no difference between the following two statements:
List<Integer> list = new ArrayList<Integer>();
List<Integer> list = new ArrayList<>();
In the first statement, the list is initialized as an ArrayList with the type parameter Integer. This means the list can only store integer values.
Generics were introduced in Java 5 (not Java 8) to address issues with type safety in collections. Before generics, lists were declared as:
List list = new ArrayList();
Such lists could store any type of object (e.g., integers, strings, etc.), which often caused runtime errors due to invalid type casting. Generics ensure compile-time type checking and prevent such issues.
In the second statement, the type parameter (<Integer>) is omitted on the right-hand side. This feature is called type inference or the diamond operator (<>), introduced in Java 7. The compiler automatically infers the type (Integer in this case) from the declaration on the left-hand side.
Hence, both statements are functionally identical. The second one is simply a more concise and modern way to write the same thing.