1

I am trying to code the below snippet in Java 8 -

Scanner sc = new Scanner(System.in);
System.out.println("Enter the policy amount: ");
long amount = sc.nextInt();

System.out.println("Enter the interest: ");
int interest = sc.nextInt();

System.out.println("Enter the number of years: ");
int years = sc.nextInt();
sc.close();

for (int i = 1; i <= years; i++) {
    result = nextYear + amount;
    calculateInterest = result * interest / 100;
    nextYear = result + calculateInterest;
}
return nextYear;

I need the nextYear value so, have tried like below using IntStream

IntStream intStream = IntStream.rangeClosed(1, years);

    intStream.forEach(num -> {
        result = nextYear + amount;
        calculateInterest = result * interest / 100;
        nextYear = result + calculateInterest;
    });

but, not sure how to return the nextYear value. How to handle this or is there any other way to do this. kindly suggest. Thank you.

5
  • 1
    why do you need a for loop at all? There must surley be a formula for interest calculation. Commented Apr 9, 2021 at 15:37
  • are you trying to calculate compound interest? Commented Apr 9, 2021 at 15:40
  • Just in case if it is not about interest calculation, In general how can we do it? Kindly help. Commented Apr 9, 2021 at 15:40
  • Usually it'd be a reduce operation. But also usually you don't reduce when you just have a loop but when you intend to base the result on the contents of the stream. Commented Apr 9, 2021 at 15:43
  • 4
    Java 8 (even 16) still allows for loops... nothing wrong with them. I would only use streams if the code can be better expressed with streams (or for fun/testing) - very opinion-based Commented Apr 9, 2021 at 15:50

2 Answers 2

1

Since your result is just repeatedly applying the body of the loop, the way to get that through the stream API is through the .iterate() static method that allows you to generate a stream similarly formed of a repeat application of a function.

If we take the body of the loop and transform it, we get:

return LongStream.iterate(0, nextYear -> {
    long result = nextYear + amount;
    long calculateInterest = result * interest / 100;

    return result + calculateInterest;
})
.skip(years)
.findFirst()
.getAsLong();

Using some arithmetic, we can simplify the body of the lambda function. By inlining result and calculateInterest we get to just one line:

nextYear -> {
    return (nextYear + amount) + (nextYear + amount) * interest / 100;
}

By eliminating the body and refactoring the equation via grouping we get

nextYear -> ((nextYear + amount) * (100 + interest)) / 100

The final transormation therefore looks like this:

return LongStream.iterate(0, 
    nextYear -> ((nextYear + amount) * (100 + interest)) / 100
)
.skip(years)
.findFirst()
.getAsLong();
Sign up to request clarification or add additional context in comments.

Comments

1

Theoretically, you might want to use reduce with the default value as 0. The BinaryOperator's left would be that periodically updated value while the right value remains unused (it represents years - i or num in your snippets).

double nextYear = IntStream.rangeClosed(1, years)
        .mapToDouble(i -> (double) i)
        .reduce(0.0, (left, right) -> left + amount + ((left + amount) * interest / 100));

.. or more readable:

double nextYear = IntStream.rangeClosed(1, years)
        .mapToDouble(i -> (double) i)
        .reduce(0.0, (left, right) -> {
                double result = left + amount;
                return result + ((result) * interest / 100);
        });

Note: I am quite confused of the types of your nextYear, result and calculateInterest variables. You might want to change mapToDouble or the used types on the snippets above.

Note 2: However, as already said, for-loop was available before Java 8 and is available even after Java 8, so there is no reason to stop using it.

Note 3: Are you sure the calculation is correct?

2 Comments

You don't need to cast to double i.e. you can write i -> (double) i as i -> i.
Thank you, that's a great explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.