I wrote an API in which a method takes a java.util.Map
as an argument. The map provided contains data which must be ordered in insertion order. So I specifically mentioned the argument as java.util.LinkedHashMap
. But a colleague of mine asked me to just declare the argument as Map and the client should be made aware by the javadoc of API.
I dont see the point why java.util.LinkedHashMap
is a bad practice, why should I pass in interface. Isn't it unnecessary work, and could cause functionality errors if client didn't pay attention to documentation.(I know they are supposed to).
3 Answers 3
Your API has two requirements on the parameter:
- It is a
Map
- It iterates in insertion order.
LinkedHashMap
satisfies these requirements, but there is no documentation or specification anywhere that says all insertion-ordered maps must inherit from LinkedHashMap
. By specifying LinkedHashMap
you would be guaranteeing that the parameter meets your requirements, but you would also be forbidding your API's use by someone who has a Map
that iterates in the order required but happens to use a different implementation.
What if someone comes along with some custom ArrayBackedHashMap
? They've got an object that satisfies your actual requirements (Map
and iteration order), but your declaration as LinkedHashMap
prevents it from working.
In general, if you expect your code to be used by others (and most of the rest of the time too) then you should try to accept anything that meets your actual requirements. In this case, the fact that your second requirement is not officially tied to any declared type means that you should not try to use a type to enforce it. Instead, state the requirement in your JavaDoc.
-
As an additional example, consider a java.util.TreeMap in which the Comparator is based on time of insertion. It iterates in Comparator order, which is also insertion order.Patricia Shanahan– Patricia Shanahan02/13/2016 00:11:12Commented Feb 13, 2016 at 0:11
According to Josh Bloch, you should always use interface as an argument rather than its implementation unless you are using that implementation`s specific methods.
Just consider if your client has their own implementation of Map
where collection maintains the order of insertion and also has some benefits to your client (efficiency, business logic, etc.). Another example might be some new and more effective implementation of ordered Map
by Google/Eclipse/Oracle that I am not aware of.
So, unless you are using specific methods from LinkedHashMap
, you should avoid specifying it as your argument. Maybe try to sort your Map
in before inserting or focus on providing good javadoc.
Your colleague might mean that you document that the Map
must be ordered in insertion order, which requirement can be satisfied by other classes besides LinkedHashMap
.
LinkedHashMap
as a contract seems weak in any case, because it does not guarantee the order after re-insertion.
-
there wont be any re-insertion in this case. This function sets bookmarks for each page in a pdf.javaAndBeyond– javaAndBeyond02/12/2016 23:37:31Commented Feb 12, 2016 at 23:37
LinkedHashMap
, require aLinkedHashMap
. If it can function as solely aMap
, require aMap
.LinkedHashMap
, you guarantee that the map will have the required ordering property. But on the other hand, someone could have another implementation ofMap
that also satisfies the required ordering property, but which won't be usable if you require aLinkedHashMap
.