Поток Java: накопление целого числа в forEach loop [duplicate]

Есть способ сделать это БЕЗ javascript!

Вы можете использовать встроенный svg. Вы можете использовать css на svg, если он встроен. Вы должны помнить, что использование этого метода означает, что ваш svg ответит на его размер контейнера.

Попробуйте использовать следующее решение ...

HTML

SAVE $500

CSS

div {
  width: 50%; /* set your container width */
  height: 50%; /* Set your container height */

}

svg {
  width: 100%;
  height: auto;

}

text {
  transform: translate(40px, 202px);
  font-size: 62px;
  fill: #000;

}

пример: https://jsfiddle.net/k8L4xLLa/32/

Хотите что-нибудь более кричащее?

SVG также позволяют вам делать классные вещи с фигурами и мусором. Проверьте этот замечательный вариант использования для масштабируемого текста ...

https://jsfiddle.net/k8L4xLLa/14/

255
задан Freek de Bruijn 19 January 2016 в 14:17
поделиться

6 ответов

Это будет работать, но i -> i выполняет автоматическую распаковку, поэтому «чувствует» странность. Любое из следующего будет работать и лучше объяснить, что делает компилятор под капотом с вашим исходным синтаксисом:

integers.values().stream().mapToInt(i -> i.intValue()).sum();
integers.values().stream().mapToInt(Integer::intValue).sum();
315
ответ дан Necreaux 19 August 2018 в 05:06
поделиться

Вы можете использовать метод collect для добавления списка целых чисел.

List<Integer> list = Arrays.asList(2, 4, 5, 6);
int sum = list.stream().collect(Collectors.summingInt(Integer::intValue));
2
ответ дан Buddy 19 August 2018 в 05:06
поделиться

Из docs

Операции сокращения Операция сокращения (также называемая сгибом) принимает последовательность входных элементов и объединяет их в один итоговый результат повторением применение операции объединения, например, нахождение суммы или максимума набора чисел или накопление элементов в списке. Классы потоков имеют несколько форм общих операций сокращения, называемых reduce () и collect (), а также несколько специализированных редукционных форм, таких как sum (), max () или count ().

Of Конечно, такие операции могут быть легко реализованы как простые последовательные циклы, как в:

int sum = 0;
for (int x : numbers) {
   sum += x;
}

Однако есть веские причины предпочесть операцию уменьшения над мутационным накоплением, таким как приведенное выше. Мало того, что сокращение «более абстрактно» - оно работает как с потоком в целом, а не с отдельными элементами, но правильно построенная операция сокращения по своей сути является параллелизуемой, если функции (функции), используемые для обработки элементов, являются ассоциативными и без гражданства. Например, с учетом потока чисел, для которого мы хотим найти сумму, мы можем написать:

int sum = numbers.stream().reduce(0, (x,y) -> x+y);

или:

int sum = numbers.stream().reduce(0, Integer::sum);

Эти операции восстановления могут безопасно работать в параллельно с почти никакой модификацией:

int sum = numbers.parallelStream().reduce(0, Integer::sum);

Итак, для карты вы использовали бы:

integers.values().stream().mapToInt(i -> i).reduce(0, (x,y) -> x+y);

Или:

integers.values().stream().reduce(0, Integer::sum);
57
ответ дан J Atkin 19 August 2018 в 05:06
поделиться
  • 1
    То, что ОП имеет намного лучше, а также более ясным. Этот код будет включать в себя целую работу по распаковке и боксу. – JB Nizet 8 May 2015 в 13:46
  • 2
    @JBNizet Если анализ побега не устраняет бокс. Вам нужно будет попробовать, чтобы посмотреть, если это возможно. – Peter Lawrey 8 May 2015 в 13:47
  • 3
    (x, y) - & gt; x + y необходимо распаковать x и y, суммировать их, а затем поместить результат. И снова начните добавлять результат со следующим элементом потока, и снова и снова. – JB Nizet 8 May 2015 в 13:50
  • 4
    Integer :: sum страдает от одной и той же проблемы. И если вы используете mapToInt (), чтобы иметь IntStream, вызов sum () на нем более прост, чем call reduce (). – JB Nizet 8 May 2015 в 13:57
  • 5
    См. docs.oracle.com/javase/8/docs/api/java/lang/… . Два аргумента Integer.sum () имеют тип int. Таким образом, два целых числа из потока должны быть распакованы для передачи в качестве аргументов метода. Метод возвращает int, но reduce () принимает BinaryOperator & lt; Integer & gt; как аргумент, который, таким образом, возвращает целое число. Таким образом, результат суммы должен быть помещен в ячейку Integer. – JB Nizet 8 May 2015 в 14:07

Я предлагаю еще 2 варианта:

integers.values().stream().mapToInt(Integer::intValue).sum();
integers.values().stream().collect(Collectors.summingInt(Integer::intValue));

Второй использует коллекцию Collectors.summingInt() , есть также сборщик summingLong(), который вы бы использовали с mapToLong.


И третий вариант: Java 8 представляет очень эффективный аккумулятор LongAdder , предназначенный для ускорения суммирования в параллельных потоках и многопоточных средах. Здесь приведен пример использования:

LongAdder a = new LongAdder();
map.values().parallelStream().forEach(a::add);
sum = a.intValue();
108
ответ дан Michael 19 August 2018 в 05:06
поделиться

Вы можете использовать метод уменьшения:

long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, (x, y) -> x + y);

или

long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, Integer::sum);
16
ответ дан Saeed Zarinfam 19 August 2018 в 05:06
поделиться
  • 1
    Существует уже такой аккумулятор для int, это Integer::sum – Alex Salauyou 25 March 2016 в 11:51
5
ответ дан Stephen Rauch 30 October 2018 в 17:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: