265

在实践中,最好返回一个这样的空列表

return Collections.emptyList();

或者像这样

return new ArrayList<Foo>();

还是这完全取决于您将如何处理返回的列表?

4

7 回答 7

325

主要区别在于它Collections.emptyList()返回一个不可变列表,即您不能向其中添加元素的列表。(同样适用List.of()于 Java 9 中引入的。)

在极少数情况下,您确实想要修改返回的列表,Collections.emptyList()因此List.of()不是一个好的选择。

我想说,只要合同(文档)没有明确说明不同,返回一个不可变列表就很好(甚至是首选方式)。


此外,emptyList() 可能不会在每次调用时创建新对象。

此方法的实现不需要为每个调用创建单独的 List 对象。使用此方法的成本可能与使用同名字段的成本相当。(与此方法不同,该字段不提供类型安全。)

外观的实现emptyList如下:

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

因此,如果您的方法(返回一个空列表)经常被调用,这种方法甚至可以在 CPU 和内存方面为您提供稍微更好的性能。

于 2011-04-05T13:04:18.943 回答
55

从 Java 5.0 开始,您可以指定容器中元素的类型:

Collections.<Foo>emptyList()

我同意其他回答,对于您想要返回一个空列表并保持为空的情况,您应该使用这种方法。

于 2011-10-13T17:44:00.440 回答
30

Collections.emptyList是不可变的,因此两个版本之间存在差异,因此您必须考虑返回值的用户。

返回new ArrayList<Foo>总是会创建对象的一个​​新实例,因此它有一个非常小的额外成本与之相关,这可能会给你一个使用的理由Collections.emptyList。我喜欢使用emptyList只是因为它更具可读性。

于 2011-04-05T13:03:47.297 回答
18

不过要小心。如果您返回Collections.emptyList()然后尝试对其进行一些更改,add()或者像那样做一些更改,您将有一个UnsupportedOperationException()因为Collections.emptyList()返回一个不可变对象。

于 2016-07-06T06:36:47.883 回答
8

如果Collections.emptyList()返回的列表没有被以任何方式修改(因为列表是不可变的),我会选择,否则我会选择选项 2。

这样做的好处Collections.emptyList()是每次都返回相同的静态实例,因此每次调用都不会创建实例。

于 2011-04-05T13:07:33.810 回答
3

如果Collections.emptyList()您想确保返回的列表永远不会被修改,请使用此选项。

这是调用时返回的内容emptyList()

/**
 * The empty list (immutable). 
 */
public static final List EMPTY_LIST = new EmptyList();
于 2012-04-24T08:43:04.967 回答
3

给定的答案强调emptyList()返回不可变List但不提供替代方案的事实。构造函数的ArrayList(int initialCapacity)特殊情况0因此返回new ArrayList<>(0)而不是new ArrayList<>()也可能是一个可行的解决方案:

/**
 * Shared empty array instance used for empty instances.
 */
private static final Object[] EMPTY_ELEMENTDATA = {};

[...]

/**
 * Constructs an empty list with the specified initial capacity.
 *
 * @param  initialCapacity  the initial capacity of the list
 * @throws IllegalArgumentException if the specified initial capacity
 *         is negative
 */
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

(来自 Java 1.8.0_72 的来源)

于 2016-02-15T07:42:07.853 回答