I'm learning java 8 and I wrote code that finds the count of collection element, which strings contain digits with sum more than 10.
For example:
"56abc" - this string contains sum of 11 and satisfies the condition of the task
"56" - this string also contains sum of 11 and satisfies the condition of the task
"12sdf" - this string contains sum of 3 and does not satisf the condition of the task
My code works, but I think it's too large and bad. Is there a way to make it better? Thanks!
List<String> listString = Arrays.asList("83d","349d", "12");
Stream<String> s1 = listString.stream(); //get stream of string elements
Stream<IntStream> s2 = s1.map(x->x.chars()); //get stream of chars
Stream<Stream<Integer>> s3 = s2.map(IntStream::boxed); //convert IntStream to Stream<Integer>
Stream<Stream<String>> s4 = s3.map(x->x.map(val->String.valueOf((char)val.intValue()))); //convert Stream<Integer> to Stream<String>
Stream<Stream<String>> s5 = s4.map(x->x.filter(val->val.matches("\\d+"))); //filter chars, that is not a digit
Stream<Stream<Integer>> s6 = s5.map(x->x.map(Integer::parseInt)); //convert String to Integer
Stream<Integer> s7 = s6.map(x->x.mapToInt(val->val).sum()); //find sum of digits
Stream<Integer> s8 = s7.filter(val->val>10); //filter sums that is less of 10
long count = s8.count(); //get count of elements
System.out.println("count = "+count);
First of all, it defeats the purpose to assign each intermediate Stream
to a variable. Just chain all the method calls.
Second of all, you can achieve the same result which much fewer steps.
For each IntStream
, filter out all the characters that are not between '0' and '9', map the remaining characteres to their numeric values and sum them.
List<String> listString = Arrays.asList("83d","349d", "12");
long count = listString.stream()
.map(x->x.chars())
.filter(x -> x.filter(i -> i >= '0' && i <= '9')
.map(i -> i - '0')
.sum() > 10)
.count();
System.out.println("count = " + count);