Java中關於size()>0 和isEmpt()的性能考量

size()>0 和isEmpt()性能考量

為何要寫這篇呢?主要是要糾正一個長期以來的誤區:size()>0 一定比isEmpt()性能差。

以下內容是社區裡的結論

  • 方法一(數據量大,效率低):if(list!=null && list.size()>0){}
  • 方法二(數據量大,效率高): if(list!=null && !list.isEmpty()){}

sonar的規范是這樣描述:

Collection.isEmpty() should be used to test for emptiness

Using Collection.size() to test for emptiness works, but using Collection.isEmpty() makes the code more readable and can be more performant. The time complexity of any isEmpty() method implementation should be O(1) whereas some implementations of size() can be O(n).

明白瞭吧!

主要是語義更明確,其實判斷List、Map、Set是否為空及效率比較真的沒有多大的必要,確實是沒有大多的提升。看源碼:

ArrayList:

public int size() {
    return size;
}
public boolean isEmpty() {
    return size == 0;
}

HashSet:

public int size() {
    return map.size();
}
public boolean isEmpty() {
    return map.isEmpty();
}

ConcurrentHashMap:

public int size() {
    long n = sumCount();
    return ((n < 0L) ? 0 :
            (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE :
            (int)n);
}
public boolean isEmpty() {
    return sumCount() <= 0L; // ignore transient negative values
}

其次,有些時候確實它更快,如果你使用瞭ConcurrentLinkedQueue、NavigableMap、NavigableSet,看源碼:

ConcurrentSkipListMap

public int size() {
    long count = 0;
    for (Node<K,V> n = findFirst(); n != null; n = n.next) {
        if (n.getValidValue() != null)
            ++count;
    }
    return (count >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count;
}
public boolean isEmpty() {
    return findFirst() == null;
}

最後,計算機是門需要刨根問底(點進源碼看看)的技術活,不能人雲亦雲。綜上所述,isEmpt的確是更好的選擇。

list.size() > 0 && list != null 和 list != null && list.size()>0區別

使用場合

  • list==null; 此時list還沒有實例化(new);
  • list.size()==0; 此時表明list已經實例化瞭,但list集合裡面沒有元素,長度為0

區別

如果list集合還未實例化,可用list != null && list.size() > 0進行判斷,

如果用list.size() > 0 && list != null 進行判斷的話,會報異常,因為list.size()用 在已經實例化的情況下,但現在未實例化,所以出錯;

如果list集合已經實例化,則list != null && list.size() > 0 和 list.size() > 0 && list != null 兩者都可以進行判斷。

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: