You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8使用Stream流实现List转Map(键为字符串值为长度)

问题背景
  • 现有一个存储String类型元素的list
  • 需求:将每个字符串作为key,对应字符串的长度作为value存入Map(如HashMap)
  • 已知约束:List内所有字符串均唯一,不存在重复key场景

用户当前编写的无法正常运行的代码如下:

List<String> ls = Arrays.asList("James", "Sam", "Scot", "Elich");
Map<String,Integer> map = new HashMap<>();

Function<String, Map<String, Integer>> fs = new Function<>() {
    @Override
    public Map<String, Integer> apply(String s) {
        map.put(s,s.length());
        return map;
    }
};

Map<String, Integer> nmap = ls
        .stream()
        .map(fs)
        .collect(Collectors.toMap()); // 此处卡壳无法实现
System.out.println(nmap);
错误原因

你的实现逻辑完全偏离了Stream API的设计:

  1. Stream.map()的作用是将流中每个元素转换为另一个类型的单个元素,你当前的写法会把每个字符串都转换为同一个外部共享的HashMap实例,最终流内存储的是多个指向同一个Map的引用,根本无法通过toMap()收集得到你要的键值对结构。
  2. 在Stream操作中修改外部共享变量属于带副作用的写法,并行流场景下会出现线程安全问题,不符合函数式编程的规范。
最简实现

因为不存在重复key,直接调用Collectors.toMap()的双参数重载即可,不需要额外定义中间Function、不需要提前初始化Map:

List<String> ls = Arrays.asList("James", "Sam", "Scot", "Elich");
Map<String, Integer> nmap = ls.stream()
        .collect(Collectors.toMap(
                str -> str,         // key为字符串本身
                String::length      // value为字符串长度
        ));
System.out.println(nmap);

运行输出:

{James=5, Scot=4, Elich=5, Sam=3}

如果你确实要使用map中间操作(属于冗余写法,不推荐),可以先将每个字符串转换为键值对Entry,再统一收集:

List<String> ls = Arrays.asList("James", "Sam", "Scot", "Elich");
Map<String, Integer> nmap = ls.stream()
        .map(str -> new AbstractMap.SimpleEntry<>(str, str.length()))
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue
        ));

该写法最终效果和最简实现完全一致,只是多了一步创建Entry对象的开销,日常开发优先选择第一种写法。

内容的提问来源于stack exchange,提问作者SUVAM ROY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 05:31:36