Search code examples
foreachjava-8java-streambigdecimal

How to create BigDecimal stream from String array in Java 8?


My task is to order BigDecimals given as String array. My idea is to use the String parameter constructor of BigDecimal, then sort it, then print them out with forEach. This is the code part:

Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String[] s = new String[n + 2];
for (int i = 0; i < n; i++) {
    s[i] = sc.next();
}
Stream.of(s)
    .map(i -> new BigDecimal(i))
    .sorted((bg1, bg2) -> bg1.compareTo(bg2))
    .forEach(System.out::println);            //line 22

But I got this NullPointerException for the forEach line:

Exception in thread "main" java.lang.NullPointerException
    at java.math.BigDecimal.<init>(BigDecimal.java:806)
    at Solution.lambda$main$1(Solution.java:20)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
    at Solution.main(Solution.java:22)

I'm looking forward to hearing from a streams expert.
Thank you!


Solution

  • You have declared your s array to be n + 2 elements, but you have only filled the first n. So when the stream gets to the last two elements you get a failure because BigDecimal does not accept null as the constructor argument.

    You can either create the array with just n elements (new String[n]) or just stream the first n elements using:

    Arrays.stream(s, 0, n)
    

    You can also simplify the stream to:

    Arrays.stream(s, 0, n)
          .map(BigDecimal::new)
          .sorted()
          .forEachOrdered(System.out::println);
    

    Note you should really use forEachOrdered if you want to be sure the output is in order.