Armstrong numbers in a given range using Java 8 (Follow Up) Previous Question: Armstrong numbers in a given range using Java 8

Updated program for getting all Armstrong Numbers between 1 and 10_000_000 as per the suggestions in this answer.

public class ArmstrongNumbers {

    public static void main(String[] args) {
        IntStream.range(1, 10_000_000)
                .filter((n) -&gt; {
                    int size = Integer.toString(n).length();
                    return Integer.toString(n)
                            .chars()
                            .map(d -&gt; d - '0')
                            .mapToDouble(v -&gt; Math.pow(v, size))
                            .sum() == n;
                }).forEach(System.out::println);
    }

}


Output:

1
2
3
4
5
6
7
8
9
153
370
371
407
1634
8208
9474
54748
92727
93084
548834
1741725
4210818
9800817
9926315


Comments:


Was able to replace the while loop with a stream.
Code isn't shorter but is more readable.


Can this program be made even shorter? Any other suggestions also welcome.
Looking at the code for Integer.toString, it seems to be a lot of work to convert an integer to a string. At the moment, you're doing the conversion twice.

However, getting the length of a string, via String.length, is a simple getter. As such, you'd probably be better off with storing the string representation in a variable, and calling .length() on that.

public static void main(String[] args) {
    IntStream.range(1, 10_000_000)
            .filter((n) -&gt; {
                final String number = Integer.toString(n);
                return number.chars()
                        .map(d -&gt; d - '0')
                        .mapToDouble(v -&gt; Math.pow(v, number.length()))
                        .sum() == n;
            }).forEach(System.out::println);
}


Also, good job coming up with the idea of substracting '0' from each character to cast it back to a number: that's a far better idea than what I had in mind (using complicated parse functions).

You could, in theory, perform this step at .mapToDouble, via Math.pow((v - '0'), number.length()) but I'm not sure whether that helps the readability. It does make things a lot shorter, I guess.

A potential performance upgrade after this would be to consider storing the result of Math.pow in a lookup table; whenever you surpass the current digit length, multiply each value of the lookup table by its index and continue. Right now, this doesn't seem very relevant to me, but later, this might be an issue.