当前位置: 首页 > news >正文

使用 HashMap 优化嵌套循环:Java 对象数组转换

本文旨在提供使用 HashMap 优化 Java 嵌套循环的有效方法,特别是当循环涉及对象数组并进行相等检查时。通过将内部循环转换为 HashMap 查询可以显著降低时间复杂性,提高代码性能。本文将提供详细的步骤和示例代码,以帮助读者理解和应用此优化技能。

包括嵌套循环在内的处理 Java 特别是当需要对两个对象列表进行比较,并根据特定条件进行匹配时,性能往往成为一个关键问题。 传统嵌套循环方法的时间复杂性是 O(n*m),其中 n 和 m 两个列表的长度。当列表很大时,这种方法可能会变得非常耗时。本文将介绍如何使用它 HashMap 优化这类代码,将时间复杂度降低到接近 O(n+m)。

问题描述

假设我们有两个 Java Object1的对象 和 Object2。Object1 包括字符串属性和一个字符串属性 Object2 列表。我们的目标是遍历 Object1 列表,为每一个 Object1 找到所有名称属性匹配的对象 Object2 对象,然后把这些 Object2 对象添加到 Object1 的列表中。

立即学习“Java免费学习笔记(深入);

public class Object1 { String name; String xyz; List<Object2> listobject2; public String getName() { return name; } public void setlistobject2(List<Object2> listobject2) { this.listobject2 = listobject2; } } public class Object2 { String name; String abc; String def; public String getName() { return name; } }

实现嵌套循环的传统方法是:

public void fillNestedObject() { List<Object1> listobjectt1 = new ArrayList<>(); // 假设 fetchobjects1FromApi() 从 API 获取 Object1 列表 // 实际使用时,请替换为真实数据源 listobjectt1.add(new Object1(); listobjectt1.get(0).name = "test"; List<Object2> listobject2 = new ArrayList<>(); // 假设 fetchobjectsFromapi2 从 API 获取 Object2 列表 // 实际使用时,请替换为真实数据源 Object2 obj2 = new Object2(); obj2.name = "test"; listobject2.add(obj2); for(Object1 object1 : listobjectt1){ List<Object2> tmpList = new ArrayList<>(); for(Object2 object2 : listobject2) { if(object1.getName().equals(object2.getName())){ tmpList.add(object2); } } object1.setlistobject2(tmpList); } }

使用 HashMap 优化

我们可以使用上述代码进行优化 HashMap 来存储 Object2 对象,以其 name 属性作为键。这样,我们就可以了 O(1) 在复杂的时间内搜索和 Object1 对象匹配的 Object2 对象,从而避免内部循环。

以下是使用 HashMap 优化代码:

import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class NestedLoopOptimization { public void fillNestedObject() { List<Object1> listobjectt1 = new ArrayList<>(); // 假设 fetchobjects1FromApi() 从 API 获取 Object1 列表 // 实际使用时,请替换为真实数据源 Object1 obj1 = new Object1(); obj1.name = "test"; listobjectt1.add(obj1); List<Object2> listobject2 = new ArrayList<>(); // 假设 fetchObjectfromApi2() 从 API 获取 Object2 列表 // 实际使用时,请替换为真实数据源 Object2 obj2 = new Object2(); obj2.name = "test"; listobject2.add(obj2); // 创建一个 HashMap,以 Object2 的 name Object2作为键的属性 对象作为值 Map<String, List<Object2>> object2Map = new HashMap<>(); for (Object2 object2 : listobject2 { if (!object2Map.containsKey(object2.getName())) { object2Map.put(object2.getName(), new ArrayList<>()); } object2Map.get(object2.getName()).add(object2); } // 遍历 Object1 列表,并使用 HashMap 查找匹配的 Object2 对象 for (Object1 object1 : listobject1 { List<Object2> tmpList = object2Map.getOrDefault(object1.getName(), new ArrayList<>()); object1.setlistobject2(tmpList); } } }

代码解释

  1. 创建 HashMap: 我们先创造一个 HashMap object2Map,用于存储 Object2 对象。键是 Object2 对象的 name 属性,值是相同的 name 属性的 Object2 对象列表。

  2. 填充 HashMap: 我们遍历 listobject2,每个 Object2 对象添加到 object2Map 中。如果 object2Map 同样的存在已经存在 name 属性键,则将 Object2 将对象添加到键对应的值列表中。否则,创建新列表并将其添加到键对应的值列表中 Object2 将对象添加到列表中,然后将键添加到列表中 object2Map 中。

  3. 使用 HashMap 寻找匹配对象: 我们遍历 listobject1,并使用 object2Map.get(object1.getName()) 查找与 Object1 对象匹配的 Object2 对象列表。getOrDefault 该方法用于处理 object1.getName() 在 object2Map 在不存在的情况下,此时返回新的空列表。

  4. 设置 Object1 的 List: 最后会找到的 Object2 列表设置在相应的位置 Object1 对象的 listobject2 属性中。

使用 Java 8 Stream 优化 (原答案)

import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; public class NestedLoopOptimization { public void fillNestedObject() { List<Object1> listobjectt1 = new ArrayList<>(); // 假设 fetchobjects1FromApi() 从 API 获取 Object1 列表 // 实际使用时,请替换为真实数据源 Object1 obj1 = new Object1(); obj1.name = "test"; listobjectt1.add(obj1); List<Object2> listobject2 = new ArrayList<>(); // 假设 fetchobjectsFromapi2 从 API 获取 Object2 列表 // 实际使用时,请替换为真实数据源 Object2 obj2 = new Object2(); obj2.name = "test"; listobject2.add(obj2); Stream<Object1> stream1 = listobjectt1.stream(); Stream<Object2> stream2 = listobject2.stream(); Map<String, List<Object2>> reduced2 = Collections.unmodifiableMap( stream2.reduce(new HashMap<>(), (a, b) -> { if (!a.containsKey(b.getName())) { a.put(b.getName(), new ArrayList<>()); } a.get(b.getName()).add(b); return a; }, (a, b) -> b)); stream1.peek(object1 -> object1.setListObject2(reduced2).get(object1.getName()))) .collect(Collectors.toList()); } }

代码解释(Stream 版本)

  1. 转换为 Stream: 首先将 listobjectt1 和 listobject2 转换为 Stream 对象。

  2. Reduce 成 Map: 使用 stream2.reduce 将 Object2 的 Stream 对象转换为一个 Map>,其中 key 是 Object2 的 name 属性,value 是具有相同 name 属性的 Object2 对象列表类似于以前手动创建的操作。 HashMap 但是使用了这个过程 Stream 聚合操作。Collections.unmodifiableMap 用于确保 Map 不可变性。


http://www.jsqmd.com/news/547426/

相关文章:

  • 3步打造专属滚动体验:让macOS设备交互更高效
  • Mission Planner如何加载天地图卫星地图?手把手教你搞定混合标注地图
  • 语言清洗令:禁用for循环的第一年——软件测试从业者的专业复盘与策略革新
  • OBS多平台直播分发终极指南:obs-multi-rtmp插件完整教程
  • 生物科技企业实验塑胶耗材专业供应商:塑料滴管/塑料试剂瓶/塑料金标卡/定量吸滴管/广口试剂瓶/摇瓶/离心管/窄口试剂瓶/选择指南 - 优质品牌商家
  • OpenClaw移动办公:Qwen3-VL:30B处理飞书移动端图片消息
  • 3分钟搞定iOS应用签名:这个免费工具让你的开发效率翻倍
  • 2026巧克力涂层机厂家+巧克力滴注机厂家+巧克力泵定制厂家+小型巧克力设备厂家一站式搜罗 - 栗子测评
  • 3步重构Windows右键菜单:ContextMenuManager实现操作效率提升40%的全攻略
  • TortoiseGit-2.18.0.1-64bit.msi Microsoft Visual C++ 2015-2022 Redistributable
  • OpenClaw技能开发:为Qwen3.5-9B编写自定义自动化模块
  • SpAtten架构深度拆解:从Top-k引擎到Crossbar设计的硬件加速秘籍
  • 反应罐源头厂家哪家好?2026优选不锈钢发酵罐厂家/乳化罐厂家推荐指南 - 栗子测评
  • Translategemma-27b-it与Anaconda环境配置:Python开发全指南
  • 3步解决手柄漂移:DS4Windows死区调校从入门到精通
  • LaTeX公式转图片:3分钟学会专业数学公式可视化
  • 3D Slicer和SimpleITK处理医学图像时,origin和direction符号不一致?一个Python脚本帮你搞定转换
  • 新手也能上手!2026年性价比拉满的专业AI论文软件
  • Edge/Chrome浏览器插件实测:免费下载腾讯会议回放视频到本地MP4(附详细安装避坑指南)
  • 突破手柄操控瓶颈:DS4Windows摇杆死区的深度调校解决方案
  • Android Studio 2023.12 新版本遇坑记:一招解决 Gradle 反射报错 ‘Unable to make field... accessible‘
  • Windows 11下用DOSBox 0.74-3一键配置MASM 6.15开发环境(附自动挂载脚本)
  • 解锁你的车载娱乐系统:MIB2 High Toolbox终极定制指南
  • 5步打造专属开源光标主题:macOS风格指针个性化全攻略
  • 3步攻克抖音直播录制难题:DouyinLiveRecorder突破性URL解析技术全解析
  • 「五级架构+全流程拆解」236页PPT揭秘:制药企业数字化转型顶层方案实战
  • 如何高效掌握BepInEx:从入门到精通的实战指南
  • 番茄小说下载器:从在线追更到离线收藏的完整解决方案
  • zip --help 还真没看懂怎么用啊?
  • 3步搞定!Jable视频下载终极指南:免费Chrome插件+本地工具完整教程