The Java Collections API offers a well-structured hierarchy of interfaces designed to hide collection implementation details. For the various
collection data structures like lists, sets, and maps, specific interfaces (java.util.List
, java.util.Set
,
java.util.Map
) cover the essential features.
When passing collections as method parameters, return values, or when exposing fields, it is generally recommended to use these interfaces instead
of the implementing classes. The implementing classes, such as java.util.LinkedList
, java.util.ArrayList
, and
java.util.HasMap
, should only be used for collection instantiation. They provide finer control over the performance characteristics of
those structures, and developers choose them depending on their use case.
For example, if fast random element access is essential, java.util.ArrayList
should be instantiated. If inserting elements at a random
position into a list is crucial, a java.util.LinkedList
should be preferred. However, this is an implementation detail your API should
not expose.
Code examples
Noncompliant code example
public class Employees {
public final HashSet<Employee> employees // Noncompliant, field type should be "Set"
= new HashSet<Employee>();
public HashSet<Employee> getEmployees() { // Noncompliant, return type should be "Set"
return employees;
}
}
Compliant solution
public class Employees {
public final Set<Employee> employees // Compliant
= new HashSet<Employee>();
public Set<Employee> getEmployees() { // Compliant
return employees;
}
}