Java Stream 分组求和并返回 List 的实现

在Java开发中,我们经常会遇到需要对集合中的数据进行分组、汇总等操作。Stream API是处理这些操作的有效工具。本文将带领你完成“Java Stream 分组求和并返回 List”这一功能的实现。

整体流程

在我们开始编写代码之前,先理清整个逻辑流程。以下是实现这一功能的步骤:

步骤 描述
1 准备数据源,创建一个集合。
2 使用 Stream 对集合进行分组。
3 对分组后的数据进行求和。
4 将结果转换为所需的形式并返回。

接下来,我们逐步实现每个步骤。

第一步:准备数据源

首先,我们需要创建一个数据源。这可以是一个对象列表,假设我们有一个 Person 类,其中包含 nameage 字段。我们将按 name 分组并求和 age

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // 创建一个 Person 对象的列表
        List<Person> people = Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Alice", 22),
            new Person("Bob", 35),
            new Person("Charlie", 30)
        );

        // 下一个步骤将使用这个集合
    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

代码解析:

  • 我们创建了一个 Person 类,包含 nameage 字段。
  • main 方法中,我们通过 Arrays.asList() 创建了一个 List<Person> 实例,用于后续操作。

第二步:使用 Stream 进行分组

接下来,使用 Java Stream API 对 people 列表进行分组。分组时,我们将使用 Collectors.groupingBy()

import java.util.Map;
import java.util.stream.Collectors;

// ...

Map<String, List<Person>> groupedByName = people.stream()
    .collect(Collectors.groupingBy(Person::getName));

// 输出分组结果
System.out.println(groupedByName);

代码解析:

  • 我们调用 people.stream() 将列表转化为 Stream。
  • collect(Collectors.groupingBy(Person::getName))name 字段进行分组,结果是一个 Map<String, List<Person>> 类型的对象。

第三步:求和操作

现在我们得到了一组按 name 分组后的 Person 对象。接下来对每个组中的 age 进行求和,我们可以使用 Collectors.summingInt()

Map<String, Integer> sumByName = people.stream()
    .collect(Collectors.groupingBy(Person::getName, 
           Collectors.summingInt(Person::getAge)));

// 输出结果
System.out.println(sumByName);

代码解析:

  • groupingBy 方法中,我们增加了一个参数,即 Collectors.summingInt(Person::getAge),它会对分组后的每个 Person 对象的 age 进行求和。
  • 最终结果是一个 Map<String, Integer> 类型的对象,键为 name,值为对应 age 的总和。

第四步:返回 List

最后,我们将结果转换为一个 List 的形式,通常使用 Java 的 ArrayList

import java.util.ArrayList;
import java.util.List;

// ...

List<Result> resultList = sumByName.entrySet().stream()
    .map(entry -> new Result(entry.getKey(), entry.getValue()))
    .collect(Collectors.toList());

// 输出最终结果列表
resultList.forEach(result -> 
    System.out.println(result.getName() + ": " + result.getTotalAge()));

代码解析:

  • entrySet().stream()Map 转换为 Stream。
  • 使用 map() 方法将每个内容转变为自定义的 Result 对象,包含 nametotalAge
  • 最后通过 collect(Collectors.toList()) 将 Stream 转换为 List。

Result 类的实现:

为了构造 Result 对象,确保存在相应的类定义。

class Result {
    private String name;
    private int totalAge;

    public Result(String name, int totalAge) {
        this.name = name;
        this.totalAge = totalAge;
    }

    public String getName() {
        return name;
    }

    public int getTotalAge() {
        return totalAge;
    }
}

结尾

通过这几步,我们已经完成了 Java Stream 的分组求和操作。你可以看到,使用 Stream API 可以使代码变得简洁且易于理解。此方法可以广泛应用于不同场景中,只需调整对象和分组的字段即可。

希望这篇文章能够帮助你更好地理解 Java Stream 的用法,熟练掌握分组求和操作,并在实际项目中运用这种技能!如有疑问,欢迎随时提问。