można przekonwertować tej funkcji do asocjacyjną funkcji, jak wyjaśniono w this answer na przykładzie List.hashCode()
. Różnica dotyczy tylko współczynnika (2
vs. 31
) i wartości początkowej (1
vs. 0
).
Może być dostosowany do zadania, które jest szczególnie proste, gdy masz losowy wejście dostępu niczym String
:
Function<String, Integer> f =
s -> IntStream.range(0, s.length()).map(i -> s.charAt(i)<<(s.length()-i-1)).sum();
Byłoby to nawet równolegle, ale jest to mało prawdopodobne, że kiedykolwiek spotkać takie humongous ciągi, które równoległa ocena przynosi korzyści. Więc co pozostaje, jest to, że większość ludzi może uznać to rozwiązanie mniej czytelny niż prosty for
pętli ...
Należy zauważyć, że powyższe rozwiązanie wykazuje różne zachowanie przepełnienia, czyli jeśli String
ma więcej niż 32 char
s, z należytym do korzystania z operatora zmiany zamiast pomnażania z dwoma.
Poprawkę dotyczącą tego problemu sprawia, że rozwiązanie jeszcze bardziej wydajne:
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();
Jeśli łańcuch posiada więcej niż 32 char
s, to tylko przetwarza ostatnich 32 char
S, który jest już wystarczające, aby obliczyć ten sam rezultat jak twoja pierwotna funkcja.
Nie możesz. Po prostu użyj starej pętli goold. –
Czy mówisz o funkcji 'f' lub' (a, b) -> 2 * a + b'? jeśli jest to 'f', myślę, że można go bezpiecznie używać w dowolnym strumieniu równoległym; jeśli jest to '(a, b) -> 2', to też będzie w porządku, ponieważ nie widzę żadnego powodu:' s.chars(). parallel(). reduce (0, (a, b) - > 2 * a + b) ' –