You can convert this function to an associative function, as explained in this answer at the example of List.hashCode()
. The difference lies only in the factor (2
vs.31
) and the start value (1
vs.0
).
It can be adapted to your task, which is especially easy when you have a random access input like a String
:
Function<String, Integer> f =
s -> IntStream.range(0, s.length()).map(i -> s.charAt(i)<<(s.length()-i-1)).sum();
This would even run in parallel, but it’s unlikely that you ever encounter such humongous strings that a parallel evaluation provides a benefit. So what remains, is that most people might consider this solution less readable than a simple for
loop…
Note that the above solution exhibits a different overflow behavior, i.e. if the String
has more than 32 char
s, due to the usage of the shift operator rather than multiplying with two.
The fix for this issue makes the solution even more efficient:
Function<String, Integer> f = s ->
IntStream.range(Math.max(0, s.length()-32), s.length())
.map(i -> s.charAt(i)<<(s.length()-i-1)).sum();
If the string has more than 32 char
s, it only processes the last 32 char
s, which is already sufficient to calculate the same result as your original function.