Summing Numbers with Java Streams – 用Java流对数字求和

最后修改: 2019年 1月 19日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this quick tutorial, we’ll examine various ways of calculating the sum of integers using the Stream API.

在这个快速教程中,我们将研究计算整数之和的各种方法 使用Stream API

For the sake of simplicity, we’ll use integers in our examples; however, we can apply the same methods to longs and doubles as well.

为了简单起见,我们将在我们的例子中使用整数;然而,我们也可以将同样的方法用于长数和双数。

2. Using Stream.reduce()

2.使用Stream.reduce()

Stream.reduce() is a terminal operation that performs a reduction on the elements of the stream.

Stream.reduce()是一个终端操作,对流的元素进行还原

It applies a binary operator (accumulator) to each element in the stream, where the first operand is the return value of the previous application, and the second one is the current stream element.

它将一个二进制运算符(累加器)应用于流中的每个元素,其中第一个操作数是前一个应用程序的返回值,第二个是当前流元素。

In the first method of using the reduce() method, the accumulator function is a lambda expression that adds two Integer values and returns an Integer value:

在使用reduce()方法的第一种方法中,累加器函数是一个lambda表达式,将两个Integer值相加并返回一个Integer值。

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
  .reduce(0, (a, b) -> a + b);

In the same way, we can use an already existing Java method:

以同样的方式,我们可以使用一个已经存在的Java方法

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
  .reduce(0, Integer::sum);

Or we can define and use our custom method:

或者我们可以定义并使用我们的自定义方法。

public class ArithmeticUtils {

    public static int add(int a, int b) {
        return a + b;
    }
}

Then we can pass this function as a parameter to the reduce() method:

然后我们可以将这个函数作为参数传递给reduce()方法。

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
  .reduce(0, ArithmeticUtils::add);

3. Using Stream.collect()

3.使用Stream.collect()

The second method for calculating the sum of a list of integers is by using the collect() terminal operation:

计算整数列表之和的第二个方法是使用collect()终端操作。

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
  .collect(Collectors.summingInt(Integer::intValue));

Similarly, the Collectors class provides summingLong() and summingDouble() methods to calculate the sums of longs and doubles, respectively.

同样,Collectors类提供了summingLong()summingDouble()方法来分别计算长数和双数的和。

4. Using IntStream.sum()

4.使用IntStream.sum()

The Stream API provides us with the mapToInt() intermediate operation, which converts our stream to an IntStream object.

Stream API为我们提供了mapToInt()中间操作,它将我们的流转换为IntStreamobject

This method takes a mapper as a parameter, which it uses to do the conversion, then we can call the sum() method to calculate the sum of the stream’s elements.

这个方法需要一个映射器作为参数,它用来做转换,然后我们可以调用sum()方法来计算流的元素之和。

Let’s see a quick example of how we can use it:

让我们来看看一个快速的例子,看看我们可以如何使用它。

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
  .mapToInt(Integer::intValue)
  .sum();

In the same fashion, we can use the mapToLong() and mapToDouble() methods to calculate the sums of longs and doubles, respectively.

以同样的方式,我们可以使用mapToLong()mapToDouble()方法来分别计算长数和双数的总和。

5. Using Stream#sum With Map

5.使用Stream#sumMap

To calculate the sum of values of a Map<Object, Integer> data structure, first we create a stream from the values of that Map. Next we apply one of the methods we used previously.

为了计算Map<Object, Integer>数据结构的数值之和,首先我们从该Map的数值创建一个流。接下来我们应用我们之前使用的方法之一。

For instance, by using IntStream.sum():

例如,通过使用IntStream.sum()

Integer sum = map.values()
  .stream()
  .mapToInt(Integer::valueOf)
  .sum();

6. Using Stream#sum With Objects

6.使用Stream#sum的对象

Let’s imagine that we have a list of objects and that we want to calculate the sum of all the values of a given field of these objects.

让我们想象一下,我们有一个对象的列表,我们想计算这些对象的一个给定字段的所有值之和

For example:

比如说。

public class Item {

    private int id;
    private Integer price;

    public Item(int id, Integer price) {
        this.id = id;
        this.price = price;
    }

    // Standard getters and setters
}

Next let’s imagine that we want to calculate the total price of all the items of the following list:

接下来让我们设想一下,我们要计算以下清单中所有物品的总价。

Item item1 = new Item(1, 10);
Item item2 = new Item(2, 15);
Item item3 = new Item(3, 25);
Item item4 = new Item(4, 40);
        
List<Item> items = Arrays.asList(item1, item2, item3, item4);

In this case, in order to calculate the sum using the methods shown in previous examples, we need to call the map() method to convert our stream into a stream of integers.

在这种情况下,为了使用前面例子中显示的方法来计算总和,我们需要调用map()方法将我们的流转换成整数流

As a result, we can use Stream.reduce(), Stream.collect(), and IntStream.sum() to calculate the sum:

因此,我们可以使用Stream.reduce(), Stream.collect(), 和IntStream.sum()来计算总数。

Integer sum = items.stream()
  .map(x -> x.getPrice())
  .reduce(0, ArithmeticUtils::add);
Integer sum = items.stream()
  .map(x -> x.getPrice())
  .reduce(0, Integer::sum);
Integer sum = items.stream()
  .map(item -> item.getPrice())
  .reduce(0, (a, b) -> a + b);
Integer sum = items.stream()
  .map(x -> x.getPrice())
  .collect(Collectors.summingInt(Integer::intValue));
items.stream()
  .mapToInt(x -> x.getPrice())
  .sum();

7. Using Stream#sum With String

7.使用Stream#sumString

Let’s suppose that we have a String object containing some integers.

假设我们有一个包含一些整数的String对象。

To calculate the sum of these integers, first we need to convert that String into an Array. Next we need to filter out the non-integer elements, and finally, convert the remaining elements of that array into numbers.

为了计算这些整数的总和,首先我们需要字符串转换成数组。接下来我们需要过滤掉非整数元素,最后,将该数组的剩余元素转换成数字。

Let’s see all these steps in action:

让我们看看所有这些步骤的行动。

String string = "Item1 10 Item2 25 Item3 30 Item4 45";

Integer sum = Arrays.stream(string.split(" "))
    .filter((s) -> s.matches("\\d+"))
    .mapToInt(Integer::valueOf)
    .sum();

8. Conclusion

8.结语

In this article, we discussed several methods of how to calculate the sum of a list of integers by using the Stream API. We also used these methods to calculate the sum of values of a given field of a list of objects, the sum of the values of a map, and the numbers within a given String object.

在这篇文章中,我们讨论了如何通过使用Stream API来计算整数列表的和的几种方法。我们还使用这些方法来计算一个对象列表的特定字段的值之和、一个地图的值之和以及一个特定String对象中的数字。

As always, the complete code is available over on GitHub.

一如既往,完整的代码可在GitHub上获得