Collections.emptyList() instead of null check?

2019-03-12 13:08发布

If I have a rarely used collection in some class which may be instantiated many times, I may sometimes resort to the following "idiom" in order to save unnecessary object creations:

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)
         ;

Now I was wondering if I couldn't eliminate those null checks using Collections.emptyList(), however then I would have to alter the if check in add() like so:

if (list == Collections.<Object>emptyList())
    list = new ArrayList<Object>();

Is there a better way to handle this other than just allocating a new empty collection every time?

EDIT: just to be clear, I would like to use Collections.emptyList(), but the above check in add() is really really ugly... I was wondering if there's a better way to do it or even a whole other way of handling this.

8条回答
ら.Afraid
2楼-- · 2019-03-12 13:51

emptyList() doesn't allocate an object each time.

I would create less of the object which contains the List so you can create the list every time.

What you can do is

private List<Object> list = Collections.emptyList();

private List<Object> listForWrite() {
    return list.isEmpty() ? list = new ArrayList<Object>() : list;
}


void add(Object object) {
    listForWrite().add(object);
}


// avoid creating an Iterator every time.
for (int i = 0, size = list.size(); i < size; i++) {
     ;
}
查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-03-12 13:56

Here's a variation on using optional as @Stas suggested, but also using the isEmpty immutable collection as originally requested in the question:

public static List<String> addElement(List<String> list, String toAdd) {
   List<String> newList = Optional.ofNullable(list).orElse(Collections.emptyList());
   newList.add(toAdd);
   return newList;
}

This approach is also the closest thing I can find to the nice ability in Javascript to use an empty array if the collection is null.

For example:

// no need to indent everything inside a null check of myObjects
for (MyObj myObj : Optional.ofNullable(myObjects).orElse(Collections.emptyList())){
    // do stuff with myObj
}
查看更多
登录 后发表回答