4

I am trying to convert this function to use Java 8 new syntax. Hopefully it will reduce the number of lines and perhaps make things clearer.

public int divisorSum(int n) {
    int sum = 0;
    for(int i = 1; i <= n; i ++) {
        if(n % i == 0) {
            sum = Integer.sum(sum, i);
        }
    }
    return sum;
}

I tried this:

IntStream.range(0, n).forEach(i -> ... )

But according to a comment on this post by Tezra apparently it is not advisable to loop using lambdas.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
GilbertS
  • 591
  • 8
  • 12
  • 3
    Can you share how you attempted to solve the problem? – Roddy of the Frozen Peas Apr 07 '20 at 17:48
  • 2
    Really? `sum = Integer.sum(sum, i);` instead of `sum = sum + i;` or `sum += i;`? – Holger Apr 08 '20 at 10:06
  • @Holger I read it somewhere in someone's code and I thought it was cool! There is also this one. `max = Math.max(4, 5)`. Awesome, right? – GilbertS Apr 08 '20 at 10:34
  • 1
    `Math.max(a, b)` can be considered a simplification over `a >= b? a: b`, not to speak of the required code for the floating point case, unlike `Integer.sum(a, b)` versus `a + b`. – Holger Apr 08 '20 at 11:10
  • @Holger `sum = Integer.sum(sum, a)` looks more readable compared to `sum += a`. No need to comprehend `+=`. You can read it in plain english: "Integer, then sum them". Especially for English speakers who read from left to right. `+=` is more like reading right to left. And there is no english word for it AFAIK – GilbertS Apr 08 '20 at 11:21
  • 2
    Since the operand order doesn’t matter for addition, it makes no sense to discuss whether it is read left to right or right to left. It’s the *assignment* which is right to left, *in all these cases*. And if you don’t like the `+=` operator, just use plain `+`. – Holger Apr 08 '20 at 11:54

4 Answers4

4

Here's the Java 8 streams implementation:

public int divisorSum(int n) {
    return IntStream.rangeClosed(1, n).filter(i -> n % i == 0).sum();
}

Note that rangeClosed, like your example, includes n. range() excludes the second parameter (it would only include up to n-1).

MyStackRunnethOver
  • 4,872
  • 2
  • 28
  • 42
3

You can achieve the same result using IntStream, filter and IntStream::sum that directly returns int since this stream is unboxed:

int sum = IntStream.rangeClosed(1, n).filter(i -> n % i == 0).sum();
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
  • because it implements the proper interface? jokes aside, I don't understand either. – Eugene Apr 07 '20 at 18:24
  • .. or I didn't put it into the method. it makes me doubt my abilities to write Java code :/ I really would like to know if there is something wrong in my answer – Nikolas Charalambidis Apr 07 '20 at 18:31
  • 3
    don't. move on. get used to random downvotes, without comments, they mean ZERO, or at least should to your personal feelings. – Eugene Apr 07 '20 at 20:56
  • @Nikolas Maybe if you're wondering why I didn't accept your answer over MyStackRunnethOver's [answer](https://stackoverflow.com/a/61086405/10597330) who answered later, it was because SO kept refusing me from accepting your answer saying I should wait. When MyStackRunnethOver posted his, it was a lot more descriptive. – GilbertS Apr 08 '20 at 10:43
3

You can do something like this

public static int divisorSum(int n) {
    return IntStream.rangeClosed(1, n)
            .filter(i -> n % i == 0)
            .sum();
}
Sneh
  • 3,527
  • 2
  • 19
  • 37
1

This can be helpful.

int sum1 = java.util.stream.IntStream.range(1, n + 1).filter(x -> n % x == 0).reduce(0, (x, y) -> x + y);

or

int sum1 = java.util.stream.IntStream.range(1, n + 1).filter(x -> n % x == 0).sum();
Derek Wang
  • 10,098
  • 4
  • 18
  • 39