Java mapToInt против Уменьшить с картой - PullRequest
0 голосов
/ 19 октября 2018

Я читал об уменьшении и только что обнаружил, что существует версия с тремя аргументами, которая может по существу выполнить уменьшение карты следующим образом:

String[] strarr = {"abc", "defg", "vwxyz"};

System.out.println(Arrays.stream(strarr).reduce(0, (l, s) -> l + s.length(), (s1, s2) -> s1 + s2));

Однако я не вижу преимуществаэтого по mapToInt с уменьшением.

System.out.println(Arrays.stream(strarr).mapToInt(s -> s.length()).reduce(0, (s1, s2) -> s1 + s2));

Оба дают правильный ответ 12, и оба, кажется, работают нормально параллельно.

Один лучше, чем другой, и еслиитак, почему?

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Является ли один лучше другого, и если да, то почему?

При первом подходе reduce существует коварная стоимость бокса .

Подход mapToInt.reduce(...) избегает этого.

Итак, идея в том, что если вы заинтересованы в суммировании, средний и другие просто используют специализации примитивного потока, поскольку они более эффективны.

Кстати, код:

Arrays.stream(strarr).mapToInt(s -> s.length()).reduce(0, (s1, s2) -> s1 + s2)

можно упростить до:

Arrays.stream(strarr).mapToInt(s -> s.length()).sum();
0 голосов
/ 19 октября 2018

Три аргумента Stream.reduce более гибкие:

<U> U reduce(U identity,
             BiFunction<U, ? super T, U> accumulator,
             BinaryOperator<U> combiner);

по сравнению с двумя аргументами IntStream.reduce, которые принимают и возвращают толькоint значения:

int reduce(int identity, IntBinaryOperator op);

В то время как accumulator в версии с тремя аргументами может принимать параметры двух различных типов:

BiFunction<Integer, String, Integer> acc = (i, str) -> i + str.length();

, что позволяет исключить дополнительные mapоперация:

Arrays.stream(strs).reduce(0, (i, str) -> i + str.length(), Integer::sum)
...