Collections.emptyList()而不是null check?

Phi*_*sky 16 java collections null empty-list

如果我在一些可能多次实例化的类中有一个很少使用的集合,我有时可能会求助于以下"成语"以节省不必要的对象创建:

List<Object> list = null;

void add(Object object) {
    if (list == null)
        list = new ArrayList<Object>();

    list.add(object);
}

// somewhere else
if (list != null)
    for (Object object : list)
         ;
Run Code Online (Sandbox Code Playgroud)

现在我想知道我是否无法使用删除那些空检查Collections.emptyList(),但是我必须改变if check in add()like:

if (list == Collections.<Object>emptyList())
    list = new ArrayList<Object>();
Run Code Online (Sandbox Code Playgroud)

除了每次分配一个新的空集合之外,还有更好的方法来处理这个问题吗?

编辑:只是为了清楚,我使用Collections.emptyList(),但上面检查add()真的很难看......我想知道是否有更好的方法来做它甚至一个完整的其他方式处理这个.

aio*_*obe 18

为了节省不必要的对象创作

这是一个非常糟糕的想法,它将使用== null支票和其他处理极端情况来丢弃您的代码(并且可能最终会在空指针异常中结束)!

现在我想知道我是否无法使用删除那些空检查 Collections.emptyList()

不,不是真的.emptyList()返回一个空列表.你可以做到

if (list.equals(Collections.<Object>emptyList()))
Run Code Online (Sandbox Code Playgroud)

但如果仍然会抛出NullPointerException list == null,那么它仍然不是你所追求的.

我的建议:始终将列表初始化为new ArrayList<Object>,或者,如果您想要从方法返回空列表,请Collections.emptyList()改用.(每次返回相同的实例,因此也不会创建不必要的对象.)

然后.isEmpty()用来检查集合是否为空.

  • @aioobe说`list.equals(Collections.<Object> emptyList())`如果`list == null`则会抛出NullPointerException.难道你不能做`集合.<Object> emptyList().equals(list)`那么? (4认同)
  • 在那些情况下,你肯定应该使用`new ArrayList <Object>()`. (2认同)
  • 我认为你有一个很好的广义习语,它是'新的ArrayList()'.这将是一个罕见的_specialized_情况,在这种情况下,你需要花费大量的内存才真正重要. (2认同)

Joh*_*nny 10

建议的答案是绝对正确的,只是小提示 - 在Java 8中,您可以使用新的Optional类来处理列表实例为空的情况,采用更实用的方法.

例如,像这样:

public static List<String> addElement(List<String> list, String toAdd) {
       List<String> newList = Optional.ofNullable(list).orElse(new ArrayList<>());
       newList.add(toAdd);
       return newList;
}
Run Code Online (Sandbox Code Playgroud)

  • 创建额外的可选对象比空检查更好吗? (2认同)

Aar*_*ron 5

这是我在一些代码中用于辅助方法的内容。确实可以很好地减少我通常在遍历列表之前必须进行的大量空检查。如果你想要一个不可变的列表,那么你可以返回一个新的列表对象而不是 Collections.emptyList

/**
 * Helper method to return an empty list if provided one is null.
 *
 * @param list the list
 * @return the provided list or an empty one if it was null
 */
private static <T> List<T> emptyIfNull(List<T> list) {
    if (list == null) {
        return Collections.emptyList();
    }
    return list;
}
Run Code Online (Sandbox Code Playgroud)

然后,您只需使用辅助方法,如下所示:

for (Object object : emptyIfNull(existingList)) { ... }
Run Code Online (Sandbox Code Playgroud)

如果列表对象为空,则辅助方法将返回静态空列表并跳过循环的内容。这是一种避免必须创建空检查来包装任何列表迭代的好方法。

仅作为示例,我已将列表的内部结构设为 Object 类型,但您显然会将其更改为对您的使用最有意义的内容。


小智 5

中有一个emptyIfNull方法package org.apache.commons.collections4;。如果提供的列表为空,它将返回一个空列表。

List<Object> list = CollectionUtils.emptyIfNull(list);
Run Code Online (Sandbox Code Playgroud)