Java 7 API 设计最佳实践 - 返回数组还是返回集合?

15

我知道这个问题在泛型出现之前已经被问过。数组在一定程度上更胜一筹,因为它强制执行返回类型,更加类型安全。

但是现在,使用最新的JDK 7,每次在设计这种类型的API时:

public String[] getElements(String type)
vs
public List<String> getElements(String type)

我总是难以想出一些好的理由,来解释应该选择返回 A Collection 还是一个 Array 或者其他方式。当选择 String[] 或者 List 作为 API 返回类型时,有什么最佳实践?或者说都可以各行其是。

我目前没有具体的案例,而是更希望得到一份通用的优缺点比较。


2
你有特殊情况考虑吗?这取决于你想要什么,每种方法都有其优缺点。 - amit
不,我更想要一个通用的比较,例如在哪种情况下Array表现更好,在哪种情况下Collections胜出,当然还有原因。 - Shengjie
3
除非需要极高的性能(几乎从不需要),否则我想不到任何情况下我会更喜欢数组而不是集合。 - Pablo
@Pablo:如果你想要保证可变性(当然你可以通过发送/返回一个ArrayList<String>来克服它。 - amit
可能是重复的问题:API java 5及更高版本:我应该返回数组还是集合? - Ciro Santilli OurBigBook.com
5个回答

14

如果你正在编写公共 API,那么你的客户通常会更喜欢集合,因为它们更易于操纵和与代码库的其余部分集成。另一方面,如果您希望您的公共 API 在高性能敏感的上下文中使用,则原始数组是首选。

如果您为自己编写代码,最好的做法是从集合类型开始,只有在涉及到明确的性能问题时才切换到数组。

数组的元素类型可以通过反射在运行时确定,因此如果这个特定的功能对您很重要,那么这将是另一个选择数组的情况。


12

这里是部分列表

数组的优点:

  • 快速
  • 天生可变
  • 您知道“您得到什么”(类型是什么),因此您可以确切地了解返回对象的行为方式。

列表的优点:

  • 行为因实际返回类型而异(例如,根据实际类型可以是可变或不可变)
  • 更好的层次结构设计
  • (根据实际类型)可能具有动态大小
  • 更直观的hashCode()equals() —— 这可能非常关键,如果作为哈希基础集合的键进行馈送。
  • 类型安全:

String[] arr1 = new String[5]; 
Object[] arr2 = arr1;
arr2[0] = new Object(); //run time error :(
List<String> list1 = new LinkedList<String>();
List<Object> list2 = list1; //compilation error :)

2
请注意,由于数组类型的协变性,它们不是完全类型安全的。声明void setFirst(Object[] xs,Object x);并调用setFirst(new Integer [2],“a”),会编译通过。 - Marko Topolnik
@MarkoTopolnik:我试图通过一个简化的例子(几分钟前的编辑)来表明它是列表的优点。 - amit
是的,我明白了。看来我忽略了那一点。当我们使用方法声明和调用作为例子时,这一点更加突出。 - Marko Topolnik
列表的另一个优点是,它可以通过 .toArray 很容易地转换为数组,而数组不能很容易地转换为列表。 - Caelum

3
如果我有选择,我会选择Collection,因为Java中可以免费获得附加的行为。
实现接口
最大的好处是,如果您返回Collection API(甚至是List、Set等),您可以轻松地更改实现(例如ArrayList、LinkedList、HashSet等),而无需更改使用该方法的客户端。
添加行为
Java的Collections类提供了许多包装器,可应用于集合,包括
1. 同步集合 2. 使集合不可变 3. 搜索、反转等...

0
在公開 API 中,返回集合非常有意義,因為它可以讓客戶端更加方便地使用各種可用的方法。如果客戶端需要特殊情況下的數組表示形式,客戶端始終可以調用 toArray()
此外,與其他模塊的集成也變得更加容易,因為大多數 API 都期望使用集合。

0
在我的观点中,这取决于返回的值将用于什么。
如果返回值将被迭代而不做其他操作,则数组是最佳选择,但如果结果将被操纵,则应选择适当的集合。
但要小心,例如,列表应允许重复项,而集合则不应该,栈应该是LIFO,而队列应该是FIFO,并且注意我使用的SHOULD,因为只有实现才能确定真正的行为。
无论如何,这确实取决于情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接