1.什麼是自定義分頁器 當我們需要在前端頁面展示的數據太多的時候,我們總不能將數據展示在一頁上面吧!這時,我們就需要自定義一個分頁器,將數據分成特定的頁數進行展示,每一頁展示固定條數的數據! 2.為什麼要用自定義分頁器 如上所說:為了將數據分成多頁進行展示,分別閱讀,方便查詢! 3.如何使用自定義分 ...
《Effective Java》第54條:返回零長度的數組或者集合,而不是null
一、問題
如果一個方法返回類型是list,如果結果為空的情況下返回null的情況並不少見,如下:
public class Shop_Version1 {
private final List<Cheese> cheesesInStock = new ArrayList<>();
public Shop_Version1(boolean initFlag) {
if (initFlag) {
cheesesInStock.add(Cheese.STILION);
}
}
/**
* @return a list containing all of the cheeses in the shop,
* or null if no cheeses are available for purchase.
*/
public List<Cheese> getCheeses() {
return cheesesInStock.isEmpty() ? null
: new ArrayList<>(cheesesInStock);
}
}
這樣做有一個壞處:調用這個方法的地方必須來處理null返回值,這樣很容易出錯。
有的認為這樣做的好處是:這樣做避免了分配零長度的容器所需要的開銷。這種說法是站不住腳的,第一,在這個級別上是沒有必要擔心性能的。第二,不需要分配零長度的集合或者數組,也可以返回它們,如下:
public class Shop_Version2 {
private final List<Cheese> cheesesInStock = new ArrayList<>();
public Shop_Version2(boolean initFlag) {
if (initFlag) {
cheesesInStock.add(Cheese.STILION);
}
}
/**
* @return a list containing all of the cheeses in the shop,
* or empty list if no cheeses are available for purchase.
*/
public List<Cheese> getCheeses() {
return new ArrayList<>(cheesesInStock);
}
}
二、分析
2.1 返回集合情況優化
如果真的分配零長度的集合損害了程式的性能,可以通過重覆返回一個不可變的零長度集合,避免了分配的執行,因為不可變對象可以被自由共用。如果返回的是集合,可以使用Collections.emptySet()或Collections.emptyList();如果返回的是映射,可以使用Collections.emptyMap()。這是一個優化,但是幾乎用不上,如下:
public class Shop_Version3 {
private final List<Cheese> cheesesInStock = new ArrayList<>();
public Shop_Version3(boolean initFlag) {
if (initFlag) {
cheesesInStock.add(Cheese.STILION);
}
}
/**
* @return a list containing all of the cheeses in the shop,
* or empty list if no cheeses are available for purchase.
*/
public List<Cheese> getCheeses() {
return cheesesInStock.isEmpty() ? Collections.emptyList()
: new ArrayList<>(cheesesInStock);
}
}
2.2 返回數組情況
返回數組與返回集合的情形一樣,它永遠不會返回null,而是返回零長度的數組。
public class Shop_RetArray_Version1 {
private final List<Cheese> cheesesInStock = new ArrayList<>();
public Shop_RetArray_Version1(boolean initFlag) {
if (initFlag) {
cheesesInStock.add(Cheese.STILION);
}
}
/**
* @return a array containing all of the cheeses in the shop,
* or empty array if no cheeses are available for purchase.
*/
public Cheese[] getCheeses() {
return cheesesInStock.toArray(new Cheese[0]);
}
}
千萬不要通過預先分配傳入toArray的數組來提升性能,這樣只會適得其反,如下:
public class Shop_RetArray_Version2 {
private final List<Cheese> cheesesInStock = new ArrayList<>();
public Shop_RetArray_Version2(boolean initFlag) {
if (initFlag) {
cheesesInStock.add(Cheese.STILION);
}
}
/**
* @return a array containing all of the cheeses in the shop,
* or empty array if no cheeses are available for purchase.
*/
public Cheese[] getCheeses() {
return cheesesInStock.toArray(new Cheese[cheesesInStock.size()]);
}
}
2.3 返回數組情況優化
如果分配零長度的數組會傷害性能,可以重覆返回同一個零長度的數組,因為所有零長度的數組都是不可變的,如下:
public class Shop_RetArray_Version3 {
private final List<Cheese> cheesesInStock = new ArrayList<>();
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Shop_RetArray_Version3(boolean initFlag) {
if (initFlag) {
cheesesInStock.add(Cheese.STILION);
}
}
/**
* @return a array containing all of the cheeses in the shop,
* or empty array if no cheeses are available for purchase.
*/
public Cheese[] getCheeses() {
return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}
}
三、總結
簡而言之,永遠不要返回null,而是返回一個零長度的數組或集合。如果返回null,那樣會使API更難以使用,也列容易出錯,而且沒有任何性能優勢。