Pregunta

Estoy usando la biblioteca de Google Collections AbstractIterator para implementar un generador. Me encontré con un problema al hacerlo; Lo reduje a un tipo más básico y reproduje el problema. Obviamente, esta reducción es exagerada para lo que hace, contando de 1 a números mediante un Iterable.

Esencialmente en el siguiente código, la versión no comentada funciona y la comentada no (proporciona un elemento nulo al final, en lugar de terminar en el último número).

¿Estoy haciendo algo mal o es un problema con la biblioteca?

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;
        }
      };
    }
  };
}

También intenté jugar con la disposición ?: (por ejemplo, prefijando el retorno y comparándolo con +1), sin resultado. Busqué un poco buscando documentación sobre esto, pero no encontré nada. Obviamente, la sintaxis ?: es solo una conveniencia, no una necesidad, pero aún así ...

¿Fue útil?

Solución

Obtiene una NullPointerException debido al uso del operador ternario, expresión condicional, con diferentes tipos numéricos. Java tiene reglas complejas al mezclar valores numéricos de diferentes tipos en expresiones ternarias: JLS Sección 15.25 .

Dado que endOfData () está precedido para devolver Integer , mientras que localcount es un int , Java unboxes el valor de endOfData () . Sin embargo, dado que endOfData () devuelve un valor nulo, la operación de desempaquetado resulta en una excepción de puntero nulo.

Puede continuar utilizando la instrucción if o declarar localcount como Integer .

Otros consejos

Espero que el problema sea con el uso del operador postincremento, junto con el operador ternario también. Porque, aparte de eso, los dos fragmentos deben ser completamente equivalentes, y no es culpa del AbstractIterator si no lo son, ya que no se llama a ninguno de sus códigos en ese punto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top