Reputation: 265
Assuming we have 2 test String[], something like:
String[] test = {"","","","",""};
String[] test2 = {"Test","Name", "5.00", "NY", "Single"};
And then we append them to a list like this:
List<String[]> testList = new ArrayList<>();
testList.add(test);
testList.add(test2);
The goal of what I am trying to do is to find the sum of the dollars paid, in index 2 of each String[] using Java 8 streams. But I can't seem to filter out the String[] containing empty values in each indice. Here is my attempt:
public static void main(String[] args) {
String[] test = {"","","","",""};
String[] test2 = {"Test","Name", "5.00", "NY", "Single"};
List<String[]> testList = new ArrayList<>();
testList.add(test);
testList.add(test2);
System.out.println(testList);
testList.stream().map(Arrays::asList).filter(i -> !i.isEmpty())
.mapToDouble(columnsPerRow ->
Double.parseDouble(columnsPerRow.get(2)))
.sum();
System.out.println(testList);
}
My attempt to filter it was using filter(i -> !i.isEmpty())
The error it throws is still:
Exception in thread "main" java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at Main.lambda$main$0(Main.java:23)
at java.util.stream.ReferencePipeline$6$1.accept(ReferencePipeline.java:244)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.DoublePipeline.collect(DoublePipeline.java:500)
at java.util.stream.DoublePipeline.sum(DoublePipeline.java:411)
at Main.main(Main.java:23)
Upvotes: 1
Views: 1521
Reputation: 86252
Taking your word for it, filter out the String[] containing empty values in each indice.
String[] test = {"","","","",""};
String[] test2 = {"Test","Name", "5.00", "NY", "Single"};
double total = Stream.of(test, test2)
.filter(arr -> !Arrays.stream(arr).allMatch(String::isEmpty))
.mapToDouble(arr -> Double.parseDouble(arr[2]))
.sum();
System.out.println(total);
Output is:
5.0
My code only filters out string arrays where all the values are empty strings. So it will break with an exception if the dollar value is ""
and the array contains other non-empty strings. Which is what you should want of an array without dollar value is required to hold only empty strings. For the sake of validation. You will probably want to catch the NumerFormatException
and report a validation error. Or maybe validate the stream before doing your computation.
Upvotes: 1
Reputation: 86774
You're filtering on the wrong entity:
public static void main(String[] args)
{
String[] test = {"","","","",""};
String[] test2 = {"Test","Name", "5.00", "NY", "Single"};
String[] test3 = {"Test","Name", "13.00", "NY", "Single"};
List<String[]> testList = new ArrayList<>();
testList.add(test);
testList.add(test2);
testList.add(test3);
double sum = testList.stream()
.map(Arrays::asList)
.filter(i -> i.size() > 2 && !i.get(2).isEmpty())
.mapToDouble(columnsPerRow -> Double.parseDouble(columnsPerRow.get(2)))
.sum();
System.out.println(sum);
}
Produces 18.0
as expected.
The filter stage removes arrays that are shorter than 2 elements or where the 2nd element is empty.
Upvotes: 1
Reputation: 54148
In i -> !i.isEmpty()
, i
is the ArrayList
, and it contains ("","","","","")
si it isn't empty, you may check for the value at index 2, you can do it that way
double r = testList.stream().map(Arrays::asList)
.filter(i -> !i.isEmpty()) // ensure list not empty
.map(i -> i.get(2)) // keep only 3rd element
.filter(i -> !i.isEmpty()) // ensure string isn't empty
.mapToDouble(Double::parseDouble) // map to double
.sum();
The first .filter(i -> !i.isEmpty())
could be replaced by .filter(i -> i.size() >= 3)
Upvotes: 2