Question

I am using the Google Collections library AbstractIterator to implement a generator. I ran across a problem while doing so; I've reduced it to a more basic type and reproduced the problem. This reduction is obviously overkill for what it does, counting from 1 to numelements via an Iterable.

Essentially in the following code, the uncommented version works, and the commented one does not (provides a null element last, instead of ending on the last number).

Am I doing something wrong, or is this a problem with the library?

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

I also tried fiddling around with the ?: arrangement (e.g., prefixing the return and comparing to +1 instead), to no avail. I poked around a bit looking for documentation about this, but didn't find anything. Obviously, the ?: syntax is only a convenience, not a necessity, but still...

Was it helpful?

Solution

You get a NullPointerException because of the use of the ternary operator, conditional expression, with different numerical types. Java has complex rules when mixing numerical values of different types in ternary expression: JLS Section 15.25.

Given that endOfData() is preceived to return Integer, while localcount is an int, Java unboxes the value of endOfData(). However, given that endOfData() returns a null, the unboxing operation results into a null pointer exception.

You can either continue using the if statement, or declare localcount as Integer.

OTHER TIPS

I expect the problem is with your use of the postincrement operator, in conjunction with the ternary operator as well. Because asides from that, the two snippets should be entirely equivalent - and it's hardly the AbstractIterator's fault if they're not as none of its code is being called at that point.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top