0

My first attempt at using a stream and a lambda expression:

Stream<TableType> myTTStream = Arrays.stream( T[source] ); // T[source] is a 1D row from a 2D array
    Optional<TableType> closest = myTTStream 
            .filter( tt -> !tt.visited ) // tt is each TableType object in the stream; select for unvisited
            .sorted( (tt1, tt2) -> Integer.compare(tt1.dist, tt2.dist) ) // sort them by distance to an output stream
            .findFirst() // get the first (lowest) distance (returns a possibly empty Optional describing the first element)
            ; 
    return ( !closest.isPresent() || closest.get().dist == Integer.MAX_VALUE ) ? -1 : closest.get().dist; // have to get the value from the Optional

The code creates a stream from a row of the T[][] array, filters it for the boolean visited false, sorts the result, and returns the first (lowest-valued) item of the stream. It seems to work except when no items get through the filter, in which case findFirst() causes an error leading ultimately to a null pointer exception.

I don't understand this because findFirst() returns an Optional, which according to the docs, may be empty. So what's the problem? If it's due to the sorted() method being fed an empty stream, then why doesn't that line cause the error?

I'm pretty sure there are no null elements in the T array.

The stack trace (the code above is the body of the method "closestUnvisited"; line 238 is the ".findFirst()" call):

Exception in thread "main" java.lang.NullPointerException
at GraphM.lambda$0(GraphM.java:236)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)
at GraphM.closestUnvisited(GraphM.java:238)
at GraphM.findShortestPath(GraphM.java:167)
at GraphM.main(GraphM.java:343)
Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
user3238181
  • 115
  • 1
  • 10
  • 4
    http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it – Reimeus Nov 08 '15 at 20:07
  • 3
    Where is the NullPointer thrown? Look into the stack trace. Without this information, it's just guessing. According to the docs `findFirst` never returns `null`. – jso Nov 08 '15 at 20:10
  • Any chance there are null elements in the T[]? – laune Nov 08 '15 at 20:12
  • See edited post w/stack trace; pretty sure no nulls in T. – user3238181 Nov 08 '15 at 20:26
  • 1
    Line 236, where the exception happens, is `.filter( tt -> !tt.visited )`. So the only possible explanation is that `tt` is null. Read the stack traces. Use your debugger. Add traces in the code. You must become able to figure such problems by yourself. – JB Nizet Nov 08 '15 at 20:29
  • Thanks for the analysis, but reading from the bottom of the stack trace, the first line mentioned in the problem method is line 238, the .findFirst() call, then it descends into the stream code. Why is 238 there if the real culprit is line 236? – user3238181 Nov 08 '15 at 21:15
  • @user3238181, the topmost stack trace entry is the immediate cause of your NullPointerException, thus start analysing from top, not from the bottom. – Tagir Valeev Nov 09 '15 at 05:06

0 Answers0