我有一个包含多个列表的对象
public class Contribution<T extends MovieRequest> {
private Set<T> elementsToAdd;
private Set<T> elementsToUpdate;
private Set<Integer> numbersToDelete;
}该对象被发送到该方法。在那里,我对这些列表进行操作。
public void correctOtherTitle(
final Contribution<OtherTitle> contribution
) throws ResourceNotFoundException {
contribution.getElementsToAdd().forEach(otherTitle -> {
...
});
contribution.getNumbersToDelete().forEach(number -> {
...
});
contribution.getElementsToUpdate().forEach(otherTitleToUpdate -> {
...
});
}问题是,没有必要完成所有列表,并且其中一些列表可能为空。然后抛出NullPointerException异常。当然,可以将条件设为if,但它看起来并不美观。
if(contribution.getElementsToAdd() !- null) {
contribution.getElementsToAdd().forEach(otherTitle -> {
...
});
}看起来是致命的。你知道怎么做得更好吗?
发布于 2017-11-26 02:12:55
为了避免显式if的not null检查,您可以将Contribution类字段的类型更改为包装实际数据的Optional:
public class Contribution<T extends MovieRequest> {
private Optional<Set<T>> elementsToAdd;
private Optional<Set<T>> elementsToUpdate;
private Optional<Set<Integer>> numbersToDelete;
}并相应地调整getter。
这样,您就可以使用Optional.ifPresent(Consumer<? super T> consumer)来避免显式的not null检查:
contribution.getElementsToAdd().ifPresent(otherTitle -> {
otherTitle.forEach(m -> ...);
});这也不是非常优雅的。
但是,它在不引入中间变量的情况下减少了代码重复(这可能会产生副作用)。Getter方法确实只需调用一次。
发布于 2017-11-26 02:37:55
问题是,没有必要完成所有列表,并且其中一些列表可能为空。
我认为你应该解决问题的根源,而不是解决它。为什么这些集合可以为空?你已经有了一种“安全”的方式来表明没有什么需要添加/删除/更新的--一个空集。因此,如果这些集合在您的控制之下(事实是它们是private,而您有getters,这意味着这一点),那么您应该强制执行该不变量。
例如,您的Contribution类可能如下所示:
public class Contribution<T extends MovieRequest> {
private Set<T> elementsToAdd = new HashSet<>();
// ... same for elementsToUpdate / numbersToDelete ...
public Set<T> getElementsToAdd() {
return Collections.ummodifiableSet(elementsToAdd);
}
public void addElementToAdd(T element) {
elementsToAdd.add(element);
}
}这个模式包含了大量的样板文件。但是像Immutables这样的代码生成器对此有很大的帮助。
发布于 2017-11-26 02:46:26
没有检查not null的快捷方式,但您可以在贡献类上实现一个构造函数,并将集合初始化为空集。
此外,如果代码对您来说很重要,我可能建议您努力尝试将correctOtherTitle函数的逻辑推到Contribution类中,因为将和object传递给操作对象的方法看起来像是一个贫血域。
https://stackoverflow.com/questions/47489001
复制相似问题