最近我被告知集合应该优先于List作为EJB方法的返回值。一般来说,集合更通用,即允许您更改基础数据结构而不会影响客户端。如果这是您希望作为设计师的灵活性,那么使用集合将更有意义。但是,返回一个数组而不是集合会不会更有意义?
如果有任何性能影响?
提前致谢。
答案 0 :(得分:29)
然后您通常有4个选项:List
,Set
,Collection
和Iterable
。在那里,它取决于你想要包含的语义。
Set
List
Collection
Iterable
(注意:有一些具有更具体语义的集合接口:Queue
,Deque
,Map
,Bag
,Multiset
等 - 但是当你需要退货时,这将是相当明显的)
答案 1 :(得分:5)
一般来说,集合优于数组,尤其是Java5之后,它们被转换为通用。这为您提供了类型安全性,以及许多在数组中不可用的潜在额外功能(例如,设置/队列等行为) - 这些功能实际上根本不能与数组直接比较。在集合中,ArrayList
是数组的直接类比,并且 - 在数组之上实现 - 其性能与本机数组相当。
至于Collection vs List(或其他一些更具体的界面),我个人更喜欢更具体的界面,例如,特征和行为。列表与集合是非常不同的。在设计良好的界面中,您应该事先知道(并指定)是否返回,例如集合,出列或列表。如果你返回一个Collection,你的所有客户端都可以做(除了添加/删除元素之外)迭代它,这对他们来说可能是不够的。
答案 2 :(得分:2)
在我看来,使用与Collection
或List
这样更具体的界面相对的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更适合。