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

文章目录 1.引言 2.将List转换为Map的不同方式 2.1. 使用forEach()循环 2.2. 使用Collectors.toMap() 2.3. 使用Collectors.groupingBy() 2.4. Apache Commons Collecti……




  • 1.引言
  • 2.将List转换为Map的不同方式
    • 2.1. 使用forEach()循环
    • 2.2. 使用Collectors.toMap()
    • 2.3. 使用Collectors.groupingBy()
    • 2.4. Apache Commons Collection的MapUtils.populateMap()
    • 2.5. 使用Guava的Maps.uniqueIndex()
  • 3.结论

在日常编码中,我们经常需要从Map中获取List以满足各种需求。在这篇文章中,学习Java中如何将给定的List转换为Map

1.引言

List接口是Collection的子接口。它是有序的、基于索引的,并允许重复元素。List接口有各种实现类,如ArrayList、LinkedList等。

Map接口表示一组对象,以键值对的形式存在。Map的键始终是唯一的,意味着在Map中不允许重复的键,但可以有重复的值。Map接口有各种实现类,如HashMap、LinkedHashMap、TreeMap等。

2.将List转换为Map的不同方式

现在让我们看看通过哪些方式可以将List转换为Map。

我们有一个包含id和name字段的Employee记录。为了演示,我们创建了两个列表,

  • ‘uniqueEmployeeList’包含具有所有员工唯一id的员工数据。
  • ‘duplicateEmployeeList’包含一些员工具有重复ID的员工数据。
record Employee(int id, String name) {
}
//创建唯一的员工数据列表
List<Employee> uniqueEmployeeList = new ArrayList<>();

// 创建重复的员工数据列表
List<Employee> duplicateEmployeeList = new ArrayList<>();

//将记录添加到两个列表

2.1. 使用forEach()循环

让我们使用forEach()循环遍历员工列表,并使用put()方法将相应的键值添加到Map中。

Map<Integer, Employee> employeeMap = new HashMap<>();

for(Employee employee: uniqueEmployeeList) {

  employeeMap.put(employee.id(), employee);
}

如果我们使用包含重复员工的列表,那么在创建的Map中,旧值将被新值替换为该键。为了避免这种情况,我们可以使用ConcurrentList来存储给定键的所有Employee记录。

Map<Integer, List> employeeMapWithListValue = new HashMap<>();

for(Employee employee: duplicateEmployeeList) {
  if(employeeMapWithListValue.containsKey(employee.id())) {
    employeeMapWithListValue.get(employee.id()).add(employee);
  } else {
    ArrayList<Employee> list = new ArrayList<>();
    list.add(employee);
    employeeMapWithListValue.put(employee.id(), list);
  }
}

2.2. 使用Collectors.toMap()

自Java版本1.8以来,我们可以使用Streams和collectors通过使用toMap()方法将List转换为Map。

Map<Integer, Employee> employeeMap = uniqueEmployeeList.stream()
    .collect(Collectors.toMap(Employee::id, Function.identity()));

如果使用包含重复员工的列表,则toMap()方法会引发IllegalStateException。为解决此问题,我们必须使用toMap()方法的另一个变体,该变体将第三个参数作为合并函数,用于解决与同一键关联的值之间的冲突。

Map<Integer, List<Employee>> employeeMapWithListValue = duplicateEmployeeList.stream()
    .collect(Collectors.toMap(item -> item.id(),
        item -> new ArrayList<>(Arrays.asList(item)),
        (l1, l2) -> {
          l1.addAll(l2);
          return l1;
        }));

2.3. 使用Collectors.groupingBy()

当列表中存在重复元素并且我们想要创建一个具有唯一键和与重复键中所有值相关联的所有值的List的Map时,我们可以使用groupingBy()方法。

Map<Integer, List<Employee>> employeeMapWithListValue = duplicateEmployeeList.stream()
      .collect(Collectors.groupingBy(Employee::id,
          Collectors.mapping(Function.identity(), Collectors.toList())));

请注意程序输出,与重复的员工ID ‘1’和’2’关联的所有值都在一个List中保留,并返回一个以Integer为键,以List<Employee>为值的Map。

2.4. Apache Commons Collection的MapUtils.populateMap()

我们可以使用Apache Commons Collections库中的MapUtils类来从List创建Map。

Map<Integer, Employee> employeeMap = new HashMap<>();

MapUtils.populateMap(employeeMap, uniqueEmployeeList, Employee::id);

如果列表中存在重复值,我们可以使用Multimap类型,该类型会自动将多个值存储在与单个键映射的列表中。

Multimap employeeMultiMap = ArrayListMultimap.create();

duplicateEmployeeList.stream().forEach(e -> employeeMultiMap.put(e.id(), e));

2.5. 使用Guava的Maps.uniqueIndex()

我们可以使用Guava库的Maps类uniqueIndex()方法来从List创建Map。

Map<Integer, Employee> employeeMap = Maps.uniqueIndex(uniqueEmployeeList, Employee::id);

与上面提到的Collectors.toMap()方法一样,如果列表包含重复记录,则uniqueIndex()方法也会引发IllegalStateException。

为解决此问题,我们可以使用Guava库的MultiMaps.index()方法,该方法执行相同的操作,但返回一个Multimap(可以包含与键相关的任意数量的值),就像Collectors.groupingBy()方法一样。

ImmutableListMultimap<Integer, Employee> employeeMap = Multimaps.index(duplicateEmployeeList, Employee::id);

3.结论

我们已经学习了在Java中将List转换为Map的各种方式。我们涵盖了List包含唯一元素以及List包含重复元素的两种情况。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/9334.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

扫描二维码

关注微信客服号