Java Stream GroupBy 返回List

Java Stream是Java 8引入的一个强大的功能,它提供了一种简洁、高效的方式来处理集合数据。在Stream中,我们可以使用groupBy操作将元素按照指定的条件进行分组。本文将重点介绍如何使用Stream的groupBy操作返回一个List,同时提供代码示例和相关解释。

Stream的groupBy操作

在Java Stream中,groupBy操作是一种用于将元素按照指定条件进行分组的操作。它的语法如下:

Map<K, List<T>> groupBy(Function<T, K> classifier)

其中,classifier参数是一个函数,它用于根据元素的某个属性或条件来进行分组。groupBy操作将返回一个Map对象,其中的键是分组的条件,值是相应条件下的元素集合。

通常情况下,groupBy操作返回的值是一个Map对象,其中的值是一个List。这意味着,分组后的结果是以键值对的形式返回的。但是有时候我们可能更希望直接返回一个List,这样可以更方便地进行后续操作。

Java Stream GroupBy 返回List 的实现方法

为了实现Java Stream的groupBy操作返回一个List,我们可以借助Collectors的toCollection方法和ArrayList::new构造函数来实现。具体的代码如下所示:

List<T> groupByToList(Stream<T> stream, Function<T, K> classifier) {
    return stream.collect(Collectors.groupingBy(classifier, Collectors.toCollection(ArrayList::new)))
                 .values()
                 .stream()
                 .flatMap(List::stream)
                 .collect(Collectors.toList());
}

在这段代码中,我们首先使用Collectors.groupingBy方法将元素按照指定条件进行分组,并使用Collectors.toCollection(ArrayList::new)将分组结果存储到一个新的ArrayList中。然后,我们使用values方法获取分组结果中的值,也就是包含元素集合的List。接着,我们使用flatMap方法将这些List中的元素打平成一个Stream,最后使用Collectors.toList将其收集为一个List并返回。

代码示例

下面是一个使用Java Stream GroupBy 返回List的示例代码:

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class GroupByExample {
    public static void main(String[] args) {
        List<Person> persons = Arrays.asList(
                new Person("Alice", 20),
                new Person("Bob", 25),
                new Person("Alice", 30),
                new Person("John", 22),
                new Person("Bob", 28)
        );

        List<Person> groupedPersons = groupByToList(persons.stream(), Person::getName);

        for (Person person : groupedPersons) {
            System.out.println(person.getName() + " - " + person.getAge());
        }
    }

    static List<Person> groupByToList(Stream<Person> stream, Function<Person, String> classifier) {
        return stream.collect(Collectors.groupingBy(classifier, Collectors.toCollection(ArrayList::new)))
                     .values()
                     .stream()
                     .flatMap(List::stream)
                     .collect(Collectors.toList());
    }
}

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类,其中包含姓名和年龄两个属性。我们将一些Person对象存储在一个List中,并使用groupByToList方法将它们按照姓名进行分组。最后,我们遍历分组后的List,并打印出每个Person对象的姓名和年龄。

状态图

下面是一个使用mermaid语法绘制的状态图,展示了groupByToList方法的执行过程:

stateDiagram
    [*] --> groupByToList
    groupByToList --> groupingBy
    groupingBy --> toCollection
    toCollection --> values
    values --> flatMap
    flatMap --> toList
    toList --> [*]

在这个状态图中,我们可以看到groupByToList方法的执行路径,以及每个步骤之间的关系。

序列图

下面是一个使用mermaid语法绘制的序列图,展示了groupByToList方法的执行流程:

sequenceDiagram
    participant Stream
    participant Collect