RAS
RAS

Reputation: 197

Stream reduce incorrectly working with long type

I want convert string line to long digit. I do this:

 String line = "eRNLpuGgnON";
 char[] chars = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890-_".toCharArray();
 Map<Character, Integer> charToInt =
            IntStream.rangeClosed(0, chars.length - 1)
                    .boxed()
                    .collect(Collectors
                            .toMap(i -> (chars[i]), i -> i));

long l =  line.chars()
            .mapToObj(i -> (char) i)
            .map(charToInt::get)
            .reduce((int) 0L, ((a, b) -> a * chars.length + b));
System.out.println(l);

I take the corresponding indexes in the map by the symbol and perform the shortest operation of multiplication and addition.

Example. I have a line eRNLpuGgnON. These symbols have such values in the Map:

e=2
R=29
N=50
....

The algorithm is very simple:

0*64+2 = 2
2*64 + 29 = 157
157*64 + 50 = 10098
........

In the end, I need to get this value:

2842528454463293618

But I get this value:

-1472624462

And, if the value of the line is short enough, everything works fine. I can not understand why there is not work properly with values of the Long.

Upvotes: 0

Views: 507

Answers (1)

Jonathan
Jonathan

Reputation: 792

The issue is that you are using integers in the reduce operation, so you reach the Integer.MAX_VALUE giving you wrong results. Using long in your charToInt map is the way to go:

Map<Character, Long> charValues = IntStream.range(0, chars.length)
                .boxed()
                .collect(Collectors.toMap(i -> chars[i], Long::valueOf));

long l =  line.chars()
        .mapToObj(i -> (char) i)
        .map(charValues::get)
        .reduce(0L, (a, b) -> a * chars.length + b);

System.out.println(l);
// prints "2842528454463293618"

Upvotes: 1

Related Questions