I understand the benefit of Programming to an Interface and the benefit of using an Interface for the return type of a method:
public List<Integer> getUserIds() {
return Arrays.asList(1, 2, 3);
}
I wonder if this is still applicable when the method callers rely on a particular implementation to function correctly? For example,
public static void main(final String args[]) {
final Map<Integer, String> map = getUserIdMap();
Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
// print user name in the order of their Ids
for (final Map.Entry<Integer, String> entry : entrySet) {
System.out.println(entry.getKey() + ", " + entry.getValue());
}
}
public static Map<Integer, String> getUserIdMap() {
final Map<Integer, String> s = new TreeMap<>();
s.put(3, "Tracer");
s.put(2, "John");
s.put(5, "Jane");
s.put(6, "Jenny");
s.put(1, "Rob");
return s;
}
In this case, is it better for getUserIdMap() to return a SortedMap instead of Map so that the method caller does not need to guess the map's underlying implementation? Or is it generally better to return a Map because the method entrySet() belongs to Map?
It would be bad for client code that uses an interface to depend on an implementation detail that is not documented on the interface.
In your example, the Set
and Map
interfaces make no guarantees about the order of the elements inside them, so it would be bad for the client to make assumptions about them.
But this is not a problem in your case, as there are more specific sub-interfaces of Set
and Map
that do make guarantees about order. They are java.util.SortedSet
and java.util.SortedMap
. If your client code uses these interfaces, then they are allowed to make assumptions about order.
TreeSet
and TreeMap
implement these interfaces, respectively.
From the Javadoc for SortedMap
:
A
Map
that further provides a total ordering on its keys.