行业资讯 2025年08月6日
0 收藏 0 点赞 581 浏览 2911 个字
摘要 :

文章目录 1.注意IllegalStateException 2.将Stream转换为Map(无重复键) 3. 将Stream转换为Map(有重复键) 3.1将Stream收集到Map的List中 3.2. 将Stream收集到Map中……




  • 1.注意IllegalStateException
  • 2.将Stream转换为Map(无重复键)
  • 3. 将Stream转换为Map(有重复键)
    • 3.1将Stream收集到Map的List中
    • 3.2. 将Stream收集到Map中并丢弃重复值
  • 4.维持插入顺序或按键排序
  • 5. 结论

学习如何将Stream转换为Map,即使用Collectors.toMap()和Collectors.groupingBy()方法将Stream的项收集到Map中。

1.注意IllegalStateException

请注意,首先我们要知道Stream元素是否具有转Map后键字段的相同的情况,如果有的话,并且我们使用Collectors.toMap()方法,代码将抛出IllegalStateException。类似如下:

Exception in thread “main” java.lang.IllegalStateException:
Duplicate key 3 (attempted merging values Item[id=3, name=Item3] and Item[id=3, name=Item3])
at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:135)

2.将Stream转换为Map(无重复键)

在这种情况下,我们必须确保Stream中的每个键都是唯一的。处理完成后,我们将获得Map<K,V>,其中指定的键K仅与单个值V相关联。
为了演示目的,我们使用包含3个项目的Stream:

Stream<Item> stream = Stream.of(
  new Item(1, \"Item1\"),
  new Item(2, \"Item2\"),
  new Item(3, \"Item3\")
);

我们可以将上述Item实例的Stream转换为两种方式的Map<Long, String>:

  • Map键- Item ID
    Map值- Item Name。
Map<Long, String> mapWithValue = stream.collect(Collectors.toMap(Item::id, Item::name));
// {1=Item1, 2=Item2, 3=Item3}

在下一个示例中,我们使用Function.identity()将对象本身作为Map值来转换为Map<Long, Item>。

Map<Long, Item> map = stream.collect(Collectors.toMap(Item::id, Function.identity()));
// {1=Item[id=1, name=Item1], 2=Item[id=2, name=Item2], 3=Item[id=3, name=Item3]}

3. 将Stream转换为Map(有重复键)

如果流中有重复键的元素,有两种可能的方法来处理它:

  • 将所有值收集到List中并将它们与键关联起来
  • 仅选择一个值,并丢弃同一键的所有其他值

为了演示目的,我们使用包含五个元素的Stream,其中三个项目具有重复键’3’。

Stream<Item> streamWithDuplicates = Stream.of(
  new Item(1, \"Item1\"),
  new Item(2, \"Item2\"),
  new Item(3, \"Item3-1\"),
  new Item(3, \"Item3-2\"),
  new Item(3, \"Item3-3\")
);

3.1将Stream收集到Map的List中

如果我们想将所有键的值存储在List中,我们可以使用Collectors.groupingBy()来收集元素,形成Map<key, List>的格式。在下面的示例中,我们将项目收集到Map的List中,即Map<K, List<Item>>。

Map<Long, List<Item>> mapWithList = streamWithDuplicates.collect(Collectors.groupingBy(Item::id));

程序输出:

{
    1=[Item[id=1, name=Item1]],
    2=[Item[id=2, name=Item2]],
    3=[
            Item[id=3, name=Item3-1],
            Item[id=3, name=Item3-2],
            Item[id=3, name=Item3-3]
        ]
}

我们可以将该Stream转换为List包含Item名称的Map,即Map<K, List<String>>。

Map<Long, List<String>> mapWithGroupedValues = streamWithDuplicates
    .collect(
        Collectors.groupingBy(Item::id,
        Collectors.mapping(Item::name, Collectors.toList())));

程序输出:

{
    1=[Item1],
    2=[Item2],
    3=[Item3-1, Item3-2, Item3-3]
}

3.2. 将Stream收集到Map中并丢弃重复值

另一种方法是仅从多个值中选择一个值,并丢弃相同键的其他值。

在我们的示例中,我们可能决定选择Map键的最新名称,即item3-3,并丢弃其他值,即item3-1和item3-2。

以下代码使用第三个参数mergeFunction,当遇到键上的冲突值时,它选择必须与键关联的值。

Map<Long, Item> mapWithGrouping = streamWithDuplicates
    .collect(Collectors.toMap(Item::id, Function.identity(), (oldValue, newValue) -> newValue));

程序输出:

{
    1=Item[id=1, name=Item1],
    2=Item[id=2, name=Item2],
    3=Item[id=3, name=Item3-3]
}

4.维持插入顺序或按键排序

有时,我们可能希望维护将键值对插入Map时的顺序。 LinkedHashMap维护这样的插入顺序,因此我们可以使用它来收集Stream项。

LinkedHashMap<Long, String> mapWithValueInInsertionOrder = stream
    .collect(Collectors.toMap(
        Item::id,
        Item::name,
        (o, n) -> n,
        LinkedHashMap::new));

同样,如果我们想应用并维护Map键的排序顺序,我们可以使用TreeMap。

TreeMap<Long, String> mapwithSortedKeys = stream
    .collect(Collectors.toMap(
        Item::id,
        Item::name,
        (o, n) -> n,
        TreeMap::new));

5. 结论

本Java Stream教程讨论了将stream项收集到Map或List的多种方法。 我们看到了每种方法的示例及其输出,以便更好地了解每种方法对stream项的作用。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/9613.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号