0

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).

asked Feb 12, 2016 at 23:18
3
  • 4
    If it must function as a LinkedHashMap, require a LinkedHashMap. If it can function as solely a Map, require a Map. Commented Feb 12, 2016 at 23:19
  • you mean, if it functions only as LinkedHashMap, then LinkedHashMap should be used? Commented Feb 12, 2016 at 23:27
  • 1
    Who's going to be using the API? As I see it, there's a tradeoff here between type safety and polymorphism. On the one hand, by requiring a LinkedHashMap, you guarantee that the map will have the required ordering property. But on the other hand, someone could have another implementation of Map that also satisfies the required ordering property, but which won't be usable if you require a LinkedHashMap. Commented Feb 12, 2016 at 23:34

3 Answers 3

1

Your API has two requirements on the parameter:

  1. It is a Map
  2. 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.

answered Feb 12, 2016 at 23:46
1
  • 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. Commented Feb 13, 2016 at 0:11
1

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.

answered Feb 12, 2016 at 23:42
0
0

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.

answered Feb 12, 2016 at 23:34
1
  • there wont be any re-insertion in this case. This function sets bookmarks for each page in a pdf. Commented Feb 12, 2016 at 23:37

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.