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,因为它更具可读性和显性。什么是更好的approch 1或2?
问题是如果列表为空,我应该返回相同的列表或显式创建新的空列表并返回
答案 0 :(得分:1)
Collections.emptyList()返回Collections的一个常量成员,因此不需要花费太多时间(可以通过JIT优化)和内存。
另一方面,getListfromSomewhereElse的返回可能会锁定从其他代码返回的空列表。您可以获得任何列表类,并且可能需要一些内存。一般来说这不是问题,因为这个方法也是由你自己的团队派生,审查和测试的,但谁知道外部库中会发生什么?
例如,getListfromSomewhereElse可以将非常大的文件读入内存,然后从中删除所有元素。因此,空列表将容纳数千个元素容量,除非您/他们知道其结构并消除过多的容量。方法1将通过使用已存在的常量列表来简单地克服这一点。
作为旁注,如果您处理java 8流样式中的列表元素,您自然会获得带有.collect(Collectors.toList())步骤的新列表。但是JDK开发人员在这种情况下不强制使用emptyList。
因此,除非您确定在getListfromSomewhereElse中,否则最好返回Collections.emptyList()(或新的ArrayList()或您通过方法契约返回的任何列表类型。)
答案 1 :(得分:0)
我更喜欢
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()
无法修改。根据{{1}}的结果,getListFromSomewhereElse
的客户可能会感到困惑,有时可能会修改它获得的列表,而在某些其他情况下,它会抛出doSomething
。 E.g。
UnsupportedOperationException
将抛出UnsupportedOperationException
,而
List<String> list = someClass.doSomething(null);
list.add("A");
可能会有效,具体取决于List<String> list = someClass.doSomething("B");
list.add("A");
答案 2 :(得分:0)
很少需要做(伪代码):
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,那么可能需要感激地处理空值,但在许多情况下,完全适合记录输入不能为空,并让它抛出一个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
。