collection vs list vs arrays作为EJB方法的返回类型

时间:2011-07-12 16:48:02

标签: java java-ee collections ejb

最近我被告知集合应该优先于List作为EJB方法的返回值。一般来说,集合更通用,即允许您更改基础数据结构而不会影响客户端。如果这是您希望作为设计师的灵活性,那么使用集合将更有意义。但是,返回一个数组而不是集合会不会更有意义?

如果有任何性能影响?

提前致谢。

4 个答案:

答案 0 :(得分:29)

  • 首选数组上的集合;使用泛型
  • 使用接口而不是具体类

然后您通常有4个选项:ListSetCollectionIterable。在那里,它取决于你想要包含的语义。

  • 如果是内部API - 根据集合的特征决定它:
    • 它只保存独特的物品吗? Set
    • 客户需要随机访问吗? List
    • 客户需要修改它(添加,删除)(没有上述两个特征)? Collection
    • 客户只需要迭代它吗? Iterable
  • 如果它是一个Web服务并不重要 - 它以相同的方式序列化。

(注意:有一些具有更具体语义的集合接口:QueueDequeMapBagMultiset等 - 但是当你需要退货时,这将是相当明显的)

答案 1 :(得分:5)

一般来说,集合优于数组,尤其是Java5之后,它们被转换为通用。这为您提供了类型安全性,以及许多在数组中不可用的潜在额外功能(例如,设置/队列等行为) - 这些功能实际上根本不能与数组直接比较。在集合中,ArrayList是数组的直接类比,并且 - 在数组之上实现 - 其性能与本机数组相当。

至于Collection vs List(或其他一些更具体的界面),我个人更喜欢更具体的界面,例如,特征和行为。列表与集合是非常不同的。在设计良好的界面中,您应该事先知道(并指定)是否返回,例如集合,出列或列表。如果你返回一个Collection,你的所有客户端都可以做(除了添加/删除元素之外)迭代它,这对他们来说可能是不够的。

答案 2 :(得分:2)

在我看来,使用与CollectionList这样更具体的界面相对的Set意图有意识地完成。您将使用Collection接口来处理更具体的接口扩展Collection接口的所有实例,即真正的集合。但是,对于像Map这样代表映射而不是集合的其他接口,你不能这样做。这意味着您的EJB接口应该非常谨慎地考虑。

正如SJuan在另一个答案中指出的那样,如果您打算返回有序集合,那么必须使用List。您可以记录您的界面的这种行为,但这是缺少的;方法签名应该传达这一点。另请注意,List可能包含重复项,因此如果您打算返回没有重复项的集合,则返回Set而不是List或{更有意义{1}}。为了重申我的观点,EJB方法返回的集合应尽可能准确地反映集合的属性,而不引用具体类型;在EJB客户端的开发过程中,尝试依赖文档来传达这一点可能不会产生预期的结果。

关于使用Arrays的主题,我建议避免使用它们,尤其是Collection类型的数组。很容易滥用它们,并将它们转换为弱类型的数据传输对象,因此需要有关如何处理数组的每个元素的大量文档。相同的建议适用于集合,但大多数人倾向于滥用数组而不是集合,或者至少是我观察到的。

最后一个注释导致在集合中使用泛型。如果您的容器(以及间接的EJB规范版本)允许您为方法使用通用接口,那么请使用它们来实现额外的类型安全性。毕竟,让客户处理Object[]是一个更好的设计决策,而不是让客户处理List<DomainObject>List。我再次强调容器支持的方面,因为EJB 2.x接口不支持泛型(这是我的观察),而EJB 3.x支持泛型(但容器可能在部署或运行​​时阻塞),并且要求以特定方式对本地和远程接口进行编码; for instance WebLogic 10.3.x要求您在超级接口中指定泛型,并将其扩展为本地/远程接口。

答案 3 :(得分:1)

首先,它不仅仅是EJB的问题。这适用于所有方法定义。

事实上,参数和变量的定义也是如此:

 List<String> myList = new ArrayList<String>();

所做的定义越广泛,实施时的自由就越多。假设我定义:

 public class Numbers {
   public ArrayList getPrimesUnder(int N) {
   }
 }

假设我发现我可以使用某人的其他库方法来执行此操作,但它会返回Vector而不是ArrayList。现在,我将不得不冒险破坏调用我的方法的代码,否则我将不得不将数据从Vector复制到ArrayList。如果我将返回类型定义为List,我可以返回它的任何实例。

为什么不在这种情况下使用Collection?因为List是订购的Collection的特化。如果我想返回我订购的结果,那么我将使用List。如果没有订购,那么Collection更适合。