Java语言基于流创建映射

示例

简单的案例,没有重复的键

Stream<String> characters = Stream.of("A", "B", "C");

Map<Integer, String> map = characters
            .collect(Collectors.toMap(element -> element.hashCode(), element -> element));
// 映射= {65 = A,66 = B,67 = C}

为了使内容更具说明性,我们可以在Function-接口中使用静态方法。我们可以将λ替换为。Function.identity()element -> elementFunction.identity()

可能存在重复键的情况

Collectors.toMap状态的Javadoc :

如果映射的键包含重复项(根据Object.equals(Object)),则在执行集合操作时抛出IllegalStateException。如果映射的键可能有重复,则使用toMap(Function, Function, BinaryOperator)代替。

Stream<String> characters = Stream.of("A", "B", "B", "C");

Map<Integer, String> map = characters
            .collect(Collectors.toMap(
                element -> element.hashCode(),
                element -> element,
                (existingVal, newVal) -> (existingVal + newVal)));

// 映射= {65 = A,66 = BB,67 = C}

BinaryOperator传递给Collectors.toMap(...)生成要存储在碰撞的情况下的值。它可以:

  • 返回旧值,以便流中的第一个值优先,

  • 返回新值,以便流中的最后一个值优先,或者

  • 结合新旧值

按值分组

您可以在需要执行与数据库级联的“分组依据”操作等效的操作时使用 Collectors.groupingBy 。为了说明这一点,下面创建了一个映射,其中人的名字映射到姓氏:

List<Person> people = Arrays.asList(
    new Person("Sam", "Rossi"),
    new Person("Sam", "Verdi"),
    new Person("John", "Bianchi"),
    new Person("John", "Rossi"),
    new Person("John", "Verdi")
);

Map<String, List<String>> map = people.stream()
        .collect(
                // 函数将输入元素映射到键
                Collectors.groupingBy(Person::getName, 
                // 将输入元素映射到值的函数,
                // 如何储存值
                Collectors.mapping(Person::getSurname, Collectors.toList()))
        );

// map = {John=[Bianchi, Rossi, Verdi], Sam=[Rossi, Verdi]}