How to apply a Stream reduction (count) to a IntStream and change the return type to "int"

Related searches

This code won't compile:

public int trailingZeroes(int n) {
    return IntStream.rangeClosed(1,n)
            .filter(e -> (e  % 5) == 0)
            .count();
}

I noticed this difference in the return types of IntStream methods:

int sum() vs long count()

While trying to return an int type from the counting operation above,

  • I already understand why count() returns a long but why have sum() return a narrower return type than count()?

  • What would be the best way to achieve what I'm trying to do in my trailingZeroes method?

The sum method returns an int because the sum of two ints is an int.

The Javadoc for count says that it's equivalent to mapToLong(e -> 1L).sum(). You could use that to make your own counting that returns an int, like this:

return IntStream.rangeClosed(1,n)
        .filter(e -> (e  % 5) == 0)
        .map(e -> 1)
        .sum();

Or, because you actually know that your answer will fit in an int anyway, just cast it:

return (int) IntStream.rangeClosed(1,n)
        .filter(e -> (e  % 5) == 0)
        .count();

Java Stream reduce tutorial, Java Stream reduce tutorial shows how to perform reduction operations on Java 8 streams. sum() , min() , max() , and count() , which return one value by combining the elements of a stream. The next example adds other use cases. MyUtil. IntStream; public class JavaReduceEx3 { public static void� Java Stream reduction. A reduction is a terminal operation that aggregates a stream into a type or a primitive. The Java 8 Stream API contains a set of predefined reduction operations, such as average(), sum(), min(), max(), and count(), which return one value by combining the elements of a stream.

I already understand why count() returns a long but why have sum() return a narrower return type than count()?

sum() returns the sum of the items in the stream, so the type returned matches the type of the stream. LongStream.sum() returns long.

The count() is not directly related to the type of the objects coming from the stream, and to conform with the rest of the Stream classes they chose long, the type that represents the largest size. The count() method is actually defined at the Stream interface level, which is then extended by BaseStream, and subsequently by IntStream, so the contract of the method signature has to be preserved. (Ideally count() should have returned unsigned, but Java doesn't support unsigned.)

What would be the best way to achieve what I'm trying to do in my trailingZeroes method?

Not clear what you are trying to achieve. But I see nothing particularly wrong with it.

If you want it to return int, cast the value before returning. I presume you know that the result will always fit safely in an int (the result will always be less than n which is an int), unless you want to change the return type of your method to long.

On the other hand can't understand what this method is supposed to be doing. You could have just done:

public int trailingZeroes(int n) {
  return n / 5;
}

If you are looking for a mathematical way to determine how many trailing 0s you have in an integer, it would be different. You already have a suggested answer, so taking the liberty to suggest a recursive solution for the fun of it:

public int trailingZeroes(int n) {
   return (n % 10 != 0) 
        ? 0 
        : 1 + trailingZeroes(n / 10);
}

IntStream (Java Platform SE 8 ), Modifier and Type, Interface and Description Performs a mutable reduction operation on the elements of this stream. Returns the count of elements in this stream. Returns a stream consisting of the results of applying the given function to the Scripting on this page tracks web page traffic, but does not change the� The JDK contains many terminal operations (such as average, sum, min, max, and count) that return one value by combining the contents of a stream. These operations are called reduction operations. The JDK also contains reduction operations that return a collection instead of a single value.

count() returns a long but why have sum() return a narrower return type than count()?

From the Javadocs, IntStream.count happens to be a special case of reduction

return mapToLong(e -> 1L).sum();

which is why it returns a long. Further IntStream.sum is again a special reduction which internally uses Integer.sum

return reduce(0, Integer::sum) // signature of sum being 'int sum(int a, int b)'

which is why it returns an int.

What would be the best way to achieve what I'm trying to do in my trailingZeroes method?

A slight optimization over other solutions, you could use just map as :

public int trailingZeroes(int n) {
    return IntStream.rangeClosed(1, n)
        .map(e -> (e % 5) == 0 ? 1 : 0)
        .sum();
}

Inferring from the method name, what you should be looking for in your implementation shall be :

public int trailingZeroes(int n) {
    int count = 0;
    while (n % 10 == 0) {
        count++;
        n = n / 10;
    }
    return count;
}

which when represented in Java-9 syntax shall look like :

public int trailingZeroes(int n) {
    return (int) IntStream.iterate(n, i -> i % 10 == 0, i -> i / 10).count();
}

Guide to Stream.reduce(), Learn the key concepts of the Stream.reduce() operation in Java and use a reduce() operation on streams holding other types of elements. return values. stream().reduce(0, (a, b) -> divide(a, divider) + divide(b, divider));. }� Stream.reduce () take input as an accumulator function which takes two parameters: a partial result of the reduction (in this case, the sum of all processed integers so far) and the next element of the stream (in this case, an integer). It returns a new partial result.

sum() returns the sum of elements in this stream and since you use IntStream, sum() returns int type. Note: sum() method for LongStream will return long type.

To get int you can just use casting:

return (int)IntStream.rangeClosed(1,n)
            .filter(e -> (e  % 5) == 0)
            .count();

Java 8 Streams - Reduction, BinaryOperator is a special type (sub-interface) of BiFunction which The reduce() method iteratively apply accumulator function on the current input element. both sequential and parallel streams without making any specific changes. These methods return a state object with information such as count,� Performs a mutable reduction operation on the elements of this stream. A mutable reduction is one in which the reduced value is a mutable result container, such as an ArrayList, and elements are incorporated by updating the state of the result rather than by replacing the result. This produces a result equivalent to:

Java 8: Replace traditional for loops with IntStreams, Java 8: Replace traditional for loops with IntStreams Then we could use the iterator function. mapToObject will simply return a Stream of the type that the mapping IntStream.range(1, 5).reduce(1, (x, y) -> x * y) // > 24. Performs a mutable reduction operation on the elements of this stream. A mutable reduction is one in which the reduced value is a mutable result container, such as an ArrayList, and elements are incorporated by updating the state of the result rather than by replacing the result. This produces a result equivalent to:

IntStream range(int startInclusive, int endExclusive) returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1. Syntax : static IntStream range(int startInclusive, int endExclusive) Parameters : IntStream : A sequence of primitive int-valued elements.

Java 8 offers a possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.

Comments
  • Isn't this method just doing (int) n / 5 ?
  • @jbx No, not certainly that. It would currently count all the numbers less than N and divisible by 5. Aside: This seems though more like a mathematics problem to count the count of zeroes trailing in a number. But if I remember correctly that used to be something like (n/5 + n/25 + n/125....). Only the OP can share details.
  • @nullpointer well what the OP is doing is just taking the numbers in the range that are divisible by 5 without remainder, so dividing it by 5 and dropping the fractional part will give the same result. The range is closed, so the numbers are less than or equal to N. (If it wasn't it would have just been (int) (n - 1) / 5). And it starts from 1 (it could have even started from 5, would have been same result).
  • @jbx true, I get you what you meant now, I really think the name of the method and what it does is misleading here. Have suggested a better implementation in the answer made.
  • @nullpointer Yep saw it. Inspired me for a recursive one too :)
  • Cool use of Java 9 solution with iterate()