Однажды я работал над проектом, в котором результаты запросов были очень естественными. Но были особые случаи, когда коллекция должна быть пустой; другие случаи, когда коллекция должна содержать ровно один элемент.
Эти запросы выполнялись для объектов, которые иногда требовали сбоя в базе данных.
Подход, к которому мы наконец-то сошлись, заключался в том, чтобы возвращать результаты в нашем собственном типе (в отличие от ArrayList или чего-то еще). Для иллюстрации:
public interface Results<T> implements Iterable<T> {
Collection<T> all();
Iterator<T> iterator();
/**
* @return one value from the result, or null if the result is empty.
*/
T ifAny();
/**
* @return one value from the result.
*/
T one() throws EmptyResultException;
/**
* @return if the result is empty, returns null,
* if the result has one value, returns the value,
* if the result has more than one value, throws.
*/
T unique() throws MultiValueResultException;
/**
* @return the value if the result has exactly one; throws otherwise
*/
T exact() throws NoExactResultException;
}
Вы можете использовать аналогичный подход в вашем случае, если вам важна семантика:
public final class Result<T> {
private static final Object NON = new Object();
private final Object _value;
public Result(T value) {
if (value == null) {
throw ...
}
_value = value;
}
public T get() {
return (_value == NON) ? null : (T) _value;
}
public T use() {
if (_value == NON) {
throw ...
}
return (T) _value;
}
}
Обратите внимание, что идиомы Scala используют Option для аналогичного эффекта. Вот одна из многих ссылок на эту тему: http://www.codecommit.com/blog/scala/the-option-pattern