2016-02-12 53 views
0

我写了一个API,其中一个方法以java.util.Map作为参数。所提供的地图包含必须按广告订单排序的数据。所以我特别提到了这个说法,作为java.util.LinkedHashMap。但是我的一位同事要求我只是将参数声明为Map,并且API的javadoc应该让客户端知道。LinkedHashMap或Map

我不明白为什么java.util.LinkedHashMap是一个不好的做法,为什么我应该通过接口。这不是不必要的工作,如果客户不注意文档,可能会导致功能错误(我知道他们应该这样做)。

+4

如果它必须作为'LinkedHashMap'函数,则需要一个'LinkedHashMap'。如果它只能作为一个Map来使用,则需要一个Map。 – Vulcan

+0

你的意思是,如果它只起到LinkedHashMap的作用,那么应该使用LinkedHashMap? – user2296988

+1

谁将使用API​​?正如我所看到的,在类型安全性和多态性之间存在权衡。一方面,通过要求'LinkedHashMap',你保证地图将具有所需的排序属性。但另一方面,有人可能有另一个'Map'实现,它也满足所需的排序属性,但如果您需要'LinkedHashMap',则它将不可用。 – Ben

回答

1

你的API对参数两个要求:

  1. 这是一个Map
  2. 它在迭代插入顺序。

LinkedHashMap满足这些要求,但没有文件或规范的任何地方,说所有的插入顺序图必须从LinkedHashMap继承。通过指定LinkedHashMap,您可以保证参数符合您的要求,但是您也可能会禁止某个拥有Map的人按您要求的顺序迭代您的API,但碰巧使用其他实现。

如果有人来一些自定义ArrayBackedHashMap怎么办?他们有一个满足您的实际需求的对象(Map和迭代订单),但是您的声明为LinkedHashMap可以阻止其工作。一般来说,如果你希望别人使用你的代码(以及大部分其他时间),那么你应该尝试接受任何满足你实际需求的东西。在这种情况下,您的第二个要求不与任何声明类型正式绑定的事实意味着您不应该尝试使用某种类型来强制执行它。相反,请在JavaDoc中声明需求。

+0

作为附加示例,请考虑一个java.util.TreeMap,其中Comparator基于插入时间。它在比较器顺序中迭代,这也是插入顺序。 –

0

您的同事可能意味着您需要记录Map必须按插入顺序排列,除LinkedHashMap之外的其他类别可满足该要求。

LinkedHashMap作为一个合同在任何情况下似乎都很弱,因为它不能保证重新插入后的顺序。

+0

在这种情况下不会有任何重新插入。此功能为pdf中的每个页面设置书签。 – user2296988

1

根据乔希布洛赫,你应该总是使用接口作为参数,而不是它的实现,除非你使用该实现的具体方法。

试想,如果你的客户都有自己的执行Map其中collection保持插入的顺序和有你的客户(效率,业务逻辑等)的一些好处。另一个例子可能是谷歌/ Eclipse/Oracle订购的Map的一些新的更有效的实现,我不知道。

因此,除非您使用LinkedHashMap的特定方法,否则应避免将其指定为您的参数。也许尝试在插入之前对您的Map进行排序,或者专注于提供良好的javadoc。

+0

Thanks.makes sense – user2296988