Я хочу подвести список целых чисел. Это работает следующим образом, но синтаксис не выглядит правильным. Может ли код быть оптимизирован?
Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).sum();
java
java-8
java-stream
membersound
источник
источник
mapToLong
чтобы избежать переполнения, в зависимости от значений, которые может иметь ваша карта.i -> i
очень ясно, лично. Ну, да, вам нужно знать, что значение будет автоматически распаковано, но это правда, начиная с Java 5 ...foo(int i)
, не пишутfoo(myInteger.intValue());
каждый раз, когда они его вызывают (или, по крайней мере, я ожидаю, что нет !!). Я согласен с вами, чтоInteger::intValue
более четко, но я думаю, что то же самое применимо и здесь. Люди должны просто изучить это один раз, и тогда вы закончите :-). Это не так, как если бы это было какое-то волшебное запутывание.i -> i
выглядит как не-оп и концептуально, это не является не-оп. Конечно,Integer.intValue()
изнутри вызывается, но еще глубже скрывается, что эти методы становятся встроенными, чтобы в точности стать неактивными, как это выглядит в исходном коде.Integer::intValue
имеет бонусный момент: не нужно создавать синтетический метод в байт-коде, но это не то, что должно определять ваше решение о том, как организовать исходный код.Ответы:
Это сработает, но
i -> i
происходит автоматическая распаковка, поэтому это «странно». Любое из следующего будет работать и лучше объяснить, что компилятор делает под капотом с вашим оригинальным синтаксисом:источник
BigDecimal sum = numbers.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
Я предлагаю еще 2 варианта:
Второй использует
Collectors.summingInt()
коллектор, также естьsummingLong()
коллектор, с которым вы будете использоватьmapToLong
.И третий вариант: Java 8 представляет очень эффективный
LongAdder
аккумулятор, предназначенный для ускорения суммирования в параллельных потоках и многопоточных средах. Вот пример использования:источник
Из документов
Итак, для карты вы бы использовали:
Или:
источник
Вы можете использовать метод уменьшить:
или
источник
int
, этоInteger::sum
Long::sum
чемInteger::sum
.Вы можете использовать
reduce()
для суммирования списка целых чисел.источник
Вы можете использовать метод сбора, чтобы добавить список целых чисел.
источник
Это был бы самый короткий способ суммировать
int
массив типов (дляlong
массиваLongStream
, дляdouble
массиваDoubleStream
и т. Д.). Однако не все примитивные целочисленные типы или типы с плавающей запятой имеютStream
реализацию.источник
IntStream.of()
что не будет работать для этой проблемы, если мы не сделаем что-то похожее на привидение:IntStream.of( integers.values().stream().mapToInt( Integer::intValue ).toArray() ).sum();
integers.values().stream().mapToInt( Integer::intValue ).sum()
.Пусть это поможет тем, у кого есть объекты в списке.
Если у вас есть список объектов и вы хотите суммировать конкретные поля этого объекта, используйте ниже.
источник
Я объявил список целых чисел.
Вы можете попробовать использовать эти различные способы ниже.
С помощью
mapToInt
С помощью
summarizingInt
С помощью
reduce
источник
источник
Большинство аспектов покрыты. Но может возникнуть необходимость найти агрегацию других типов данных, кроме Integer, Long (для которых уже есть поддержка специализированных потоков). Например, Stram с BigInteger. Для такого типа мы можем использовать операцию
list.stream (). Reduce ((bigInteger1, bigInteger2) -> bigInteger1.add (bigInteger2))
источник