Java, библиотека Google Collections; проблема с AbstractIterator?
Вопрос
Я использую библиотеку Google Collections AbstractIterator для реализации генератора. При этом я столкнулся с проблемой; Я сократил его до более простого типа и воспроизвел проблему. Это сокращение явно излишне для того, что оно делает, считая от 1 до нумерации через Iterable.
По сути, в следующем коде работает некомментированная версия, а комментируемая - нет (предоставляет нулевой элемент последним, а не заканчивается последним номером).
Я что-то не так делаю, или это проблема с библиотекой?
private Iterable<Integer> elementGenerator(final int numelements) {
return new Iterable<Integer>() {
@Override public Iterator<Integer> iterator() {
return new AbstractIterator<Integer>(){
int localcount=0;
@Override protected Integer computeNext() {
if (localcount++ == numelements) return endOfData();
return localcount;
// return (localcount++ == numelements) ? endOfData() : localcount;
}
};
}
};
}
Я также попытался поиграться с расположением ?:
(например, с префиксом возврата и сравнением с +1 вместо), но безрезультатно. Я немного покопался в поисках документации по этому поводу, но ничего не нашел. Очевидно, что синтаксис ?:
- это всего лишь удобство, а не необходимость, но все же ...
Решение
Вы получаете NullPointerException
из-за использования тернарного оператора условного выражения с различными числовыми типами. Java имеет сложные правила при смешивании числовых значений различных типов в троичном выражении: Раздел 15.25 JLS
.
Учитывая, что endOfData ()
, как предполагается, возвращает Integer
, тогда как localcount
является int
, Java распаковывает значение endOfData ()
. Однако, учитывая, что endOfData ()
возвращает ноль, операция распаковки приводит к исключению нулевого указателя.
Вы можете продолжить использование оператора if или объявить localcount как Integer
.
Другие советы
Я ожидаю, что проблема заключается в использовании вами постинкрементного оператора в сочетании с троичным оператором. Потому что, кроме этого, эти два фрагмента должны быть полностью эквивалентны - и вряд ли это будет ошибка AbstractIterator, если они не таковы, поскольку ни один из его кодов не вызывается в этот момент.