[英]Good programming practice while returning empty list
List<String> doSomething(String input){
if(input == null){
return Collections.emptyList();
}
List<String> lst = getListfromSomewhereElse(input)
if(lst.isEmpty(){
return Collections.emptyList(); //Approach 1
// return lst; //Return same empty list
}
// do some more processing on lst
return lst;
}
我更喜歡方法1,因為它更具可讀性和明確性。 什么是更好的方法1或2?
問題是列表是否為空,我應該返回相同的列表還是顯式創建新的空列表並返回
Collections.emptyList()返回Collections的一個常量成員,因此不花費過多時間(可以通過JIT優化)和內存。
另一方面,getListfromSomewhereElse的返回可能會鎖定從其他代碼返回的空列表。 可能您可以獲得任何列表類,並且可能會占用一些內存。 通常這不是問題,因為此方法也由您自己的團隊派生,審查和測試,但是誰知道外部庫中發生了什么?
例如,getListfromSomewhereElse可以將很大的文件讀入內存,然后從其中刪除所有元素。 因此,空列表將容納數千個元素,除非您/他們知道其結構並擺脫了過多的能力。 方法1將通過使用已經存在的常量列表簡單地克服這一問題。
附帶說明一下,如果您以Java 8流樣式處理列表元素,則自然可以通過.collect(Collectors.toList())步驟獲得新列表。 但是在這種情況下,JDK開發人員不會強制emptyList。
因此,除非您確定在getListfromSomewhereElse中,否則最好返回Collections.emptyList()(或新的ArrayList()或通過方法協定返回的任何列表類型)。
我會比較喜歡
List<String> doSomething(String input) {
List<String> list = new ArrayList<String>();
if (input != null) {
List<String> listFromSomewhereElse = getListfromSomewhereElse(input);
list.addAll(listFromSomewhereElse);
}
return list;
}
請記住, Collections.emptyList()
是不可修改的。 取決於getListFromSomewhereElse
的結果, getListFromSomewhereElse
doSomething
的客戶端可能會感到困惑,因為它有時可以修改其獲取的列表,而在某些其他情況下,它將引發UnsupportedOperationException
。 例如
List<String> list = someClass.doSomething(null);
list.add("A");
將拋出UnsupportedOperationException
而
List<String> list = someClass.doSomething("B");
list.add("A");
可能會根據getListFromSomewhereElse
的結果工作
很少要做(偽代碼):
if(input list is empty) {
return an empty list
} else {
map each entry in input list to output list
}
...因為將輸入列表映射到輸出列表的每種主流方式都會為空輸入“自動”生成一個空列表。 例如:
List<String> input = Collections.emptyList();
List<String> output = new ArrayList<>();
for(String entry : input) {
output.add(entry.toLowerCase());
}
return output;
...將返回一個空列表。 將空列表視為特殊情況會浪費代碼,而導致表達力較低。
同樣,使用Stream
的現代Java方法具有相同的功能:
List<String> output = input.stream()
.map( s -> s.toLowerCase())
.collect(Collectors.toList());
...將在output
創建一個空列表,對空輸入不進行任何“特殊”處理。
Collections.emptyList()
返回一個專門實現不可變的空列表的類。 它有一個非常簡單的實現,例如,它的size()
僅return 0;
。
但這意味着您的呼叫者將無法修改返回的列表-僅當該列表為空時。 盡管不變性是一件好事,但有時返回不可變列表卻有時不返回不可變列表是不一致的,這可能會導致您發現較晚的錯誤。 如果要強制執行不變性,請始終通過將響應包裝在Collections.unmodifiableList()
中或使用諸如Guava之類的庫中的不變列表來實現不變性。
您還將測試輸入是否為空。 考慮是否有必要。 誰將調用該方法? 如果只有您,那就不要這樣做! 如果您知道不打算這樣做,則無需檢查代碼。
如果它是其他程序員的公共API,則可能需要感恩地處理null,但是在很多情況下,完全可以證明輸入一定不能為null,如果發生輸入,則讓它拋出NullPointerException
(或者您可以強制執行通過Objects.requireNonNull(input)
啟動方法,可以提早實現。
結論:我的建議是:
List<String> doSomething(String input){
Objects.requireNonNull(input); // or omit this and let an
// exception happen further down
return doMoreProcessingOn(getListfromSomewhereElse(input));
}
最好是doMoreProcessingOn()
產生一個新的List,而不是修改input
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.