需求假设你有一个ListPerson你想要根据每个人的ID创建一个MapInteger, Person一、一般操作import java.util.List; import java.util.Map; import java.util.stream.Collectors; class Person { private int id; private String name; // 构造器、getter和setter省略 } public class Main { public static void main(String[] args) { ListPerson people List.of(new Person(1, Alice), new Person(2, Bob), new Person(3, Charlie)); MapInteger, Person map people.stream() .collect(Collectors.toMap( //key生成策略 Person::getId, //value生成策略 person - person)); System.out.println(map); } }二、处理重复键值如果列表中有重复的ID直接使用Collectors.toMap()会抛出IllegalStateException。你可以通过提供一个合并函数来解决这个问题。MapInteger, Person mapWithDuplicates people.stream() .collect(Collectors.toMap( //key生成策略 Person::getId, //value生成策略 person - person, //冲突处理策略 (existing, replacement) - existing));三、使用Collectors.toMap()和自定义键选择器如果你想根据不同的属性例如名字来创建Map你可以提供一个自定义的键选择器。MapString, Person mapByName people.stream() .collect(Collectors.toMap( //key生成策略 Person::getName, //value生成策略 person - person));四、使用Collectors.toMap()和自定义键选择器与值转换器合并函数MapString, String namesById people.stream() .collect(Collectors.toMap( //key生成策略 person - String.valueOf(person.getId()), //value生成策略 Person::getName, //冲突处理策略 (existing, replacement) - existing)); System.out.println(namesById);注意事项重复键处理当使用Collectors.toMap()时如果列表中有重复的键你需要提供一个合并函数来决定如何处理这些重复项。如果不处理将抛出异常。自定义键你可以通过提供一个自定义的键选择器来根据任何属性创建Map。值转换除了键选择器你还可以提供一个值转换器来定义如何从流中的元素映射到Map的值。五、二级分组然后我们创建一个订单列表并对其进行二级分组import java.time.LocalDate; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { ListOrder orders Arrays.asList( new Order(Product A, LocalDate.of(2023, 4, 10)), new Order(Product B, LocalDate.of(2023, 4, 15)), new Order(Product A, LocalDate.of(2023, 5, 20)), new Order(Product C, LocalDate.of(2023, 5, 25)) ); MapInteger, MapInteger, ListOrder groupedOrders orders.stream() .collect(Collectors.groupingBy( order - order.getDate().getYear(), // 一级分组按年份分组 Collectors.groupingBy( order - order.getDate().getMonthValue() // 二级分组按月份分组 ) )); groupedOrders.forEach((year, monthMap) - { System.out.println(Year: year); monthMap.forEach((month, ordersInMonth) - { System.out.println( Month: month); ordersInMonth.forEach(order - System.out.println( Order: order.getProduct() on order.getDate())); }); }); } }
通过stream流将List转Map
需求假设你有一个ListPerson你想要根据每个人的ID创建一个MapInteger, Person一、一般操作import java.util.List; import java.util.Map; import java.util.stream.Collectors; class Person { private int id; private String name; // 构造器、getter和setter省略 } public class Main { public static void main(String[] args) { ListPerson people List.of(new Person(1, Alice), new Person(2, Bob), new Person(3, Charlie)); MapInteger, Person map people.stream() .collect(Collectors.toMap( //key生成策略 Person::getId, //value生成策略 person - person)); System.out.println(map); } }二、处理重复键值如果列表中有重复的ID直接使用Collectors.toMap()会抛出IllegalStateException。你可以通过提供一个合并函数来解决这个问题。MapInteger, Person mapWithDuplicates people.stream() .collect(Collectors.toMap( //key生成策略 Person::getId, //value生成策略 person - person, //冲突处理策略 (existing, replacement) - existing));三、使用Collectors.toMap()和自定义键选择器如果你想根据不同的属性例如名字来创建Map你可以提供一个自定义的键选择器。MapString, Person mapByName people.stream() .collect(Collectors.toMap( //key生成策略 Person::getName, //value生成策略 person - person));四、使用Collectors.toMap()和自定义键选择器与值转换器合并函数MapString, String namesById people.stream() .collect(Collectors.toMap( //key生成策略 person - String.valueOf(person.getId()), //value生成策略 Person::getName, //冲突处理策略 (existing, replacement) - existing)); System.out.println(namesById);注意事项重复键处理当使用Collectors.toMap()时如果列表中有重复的键你需要提供一个合并函数来决定如何处理这些重复项。如果不处理将抛出异常。自定义键你可以通过提供一个自定义的键选择器来根据任何属性创建Map。值转换除了键选择器你还可以提供一个值转换器来定义如何从流中的元素映射到Map的值。五、二级分组然后我们创建一个订单列表并对其进行二级分组import java.time.LocalDate; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { ListOrder orders Arrays.asList( new Order(Product A, LocalDate.of(2023, 4, 10)), new Order(Product B, LocalDate.of(2023, 4, 15)), new Order(Product A, LocalDate.of(2023, 5, 20)), new Order(Product C, LocalDate.of(2023, 5, 25)) ); MapInteger, MapInteger, ListOrder groupedOrders orders.stream() .collect(Collectors.groupingBy( order - order.getDate().getYear(), // 一级分组按年份分组 Collectors.groupingBy( order - order.getDate().getMonthValue() // 二级分组按月份分组 ) )); groupedOrders.forEach((year, monthMap) - { System.out.println(Year: year); monthMap.forEach((month, ordersInMonth) - { System.out.println( Month: month); ordersInMonth.forEach(order - System.out.println( Order: order.getProduct() on order.getDate())); }); }); } }