2017-05-13 50 views
5

我将代码重构为Java 8,我想用可选项替换空检查。java 8可选替换返回null

public Employee findEmployeeById(String id) { 
    List<Employee> empList = .. //some db query 
    return (empList.isEmpty() ? null : empList.get(0)); 
} 

Optional.ofNullable(empList.get(0))不会当它会抛出IndexOutofBoundException

或者我应该理想地Optional.empty()替换空工作?

+0

为什么你的查询只能返回一个结果呢? – Marvin

+0

这是一个复杂的逻辑....左连接和所有....我理解你指出,但不能真的改变 – coder25

+6

'返回empList.isEmpty()? Optional.empty():Optional.of(empList.get(0));' – Jesper

回答

9

由于@Jesper在评论中已经提到,您必须检查列表是否为空,然后返回空的Optional

public Optional<Employee> findEmployeeById(String id) { 
    List<Employee> empList = .. //some db query 
    return empList.isEmpty() ? Optional.empty() : Optional.of(empList.get(0)); 
} 

Optional是围绕一个潜在null值,可以让你避免null明确检查,当你使用它的包装。

看看Optional documentation看看它提供了什么功能。

例如,你可以得到一个雇员的名字或“未知”,如果它是不存在的,但不检查null

Optional<Employee> emp = findEmployeeById(id); 
String name = emp.map(Employee::getName).orElse("unknown"); 

你可以阅读this post about Uses for Optional,看它是否让你感觉使用Optional

3

你为什么不干脆用替换你的方法:

public Optional<Employee> findEmployeeById(String id) { 
    List<Employee> empList = .. //some db query 
    return (empList.isEmpty() ? Optional.empty() : 
       Optional.ofNullable(empList.get(0))); 
} 

我建议你换一个Optional.ofNullableempList.get(0)的情况下,它仍然可能为空

只要为什么这是更好的:想想方法的调用者。无论谁现在打电话给你的方法必须认为当结果为empty时,实际要做什么。

再说你现在被迫到编写代码,如:

Optional<Employee> emp = findEmployeeById("12"); 

if (emp.isPresent()) { 

} else { 
    .... 
} 

你也可以连接此变得更加流畅,如:

emp.orElseThrow(RuntimeException::new) 

或其他可选的方法。

当您退回员工时,情况根本不是。你甚至不会想(通常)检查引用是否为空。

这使得您的代码不易出错并且更易于理解。

2

另一种可能性是如下做到这一点:

return Optional.of(empList).filter(list -> !list.isEmpty()).map(list -> list.get(0)); 

的情况下,这将自动返回一个空Optional列表为空或empList.get(0)回报null

如果empList可以是null,考虑使用Optional.ofNullable(empList)而不是Optional(empList)

5

对我来说,自然的解决办法是保持你的? :结构在Floern’s answer。但是,如果你想摆脱的是,也有一个优雅的解决方案没有它:

public Optional<Employee> findEmployeeById(String id) { 
    List<Employee> empList = .. //some db query 
    return empList.stream().findFirst(); 
} 

这给你你想要什么,因为findFirst()返回Optional。如果你不关心你得到哪个元素 - 或者你知道不会有多于一个 - 你可以选择使用findAny(),它也返回Optional

+0

不错,没想过那 – Floern

+2

不错!你甚至不需要'empList' local,所以这可以归结为'return someDbQuery()。stream()。findFirst()'。 –