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

在 Java 中高效搜索 ArrayList 中的对象

本文介绍了如何在这里 Java 中搜索 ArrayList 特定对象中,重点是理解, contains() 该方法的局限性,并提供了一个基于循环的定制搜索解决方案。根据对象的属性(如产品名称),详细显示了如何根据对象的属性(如产品名称) ArrayList 寻找目标对象,并提供相关注意事项。

在 Java 中,ArrayList 用于存储对象集合的常用动态数组。当需要搜索时 ArrayList 当一个特定的对象是否存在时,通常会想到使用它 contains() 方法。但是,直接使用 contains() 找到具有特定属性的对象的方法(例如,根据产品名称找到) Product 对象)往往得不到预期的结果。 这是因为 ArrayList 的 contains() 默认使用该方法 equals() 比较对象的方法。 假如没有重写 equals() 方法,它引用比较对象,而不是对象的内容。

理解 contains() 方法的局限性

ArrayList 的 contains(Object o) 这种方法的工作原理是:遍历 ArrayList 并使用中间的每个元素 o.equals(element) 比较给定的对象 o 列表中的每个元素 element。 若找一个 element 使得 o.equals(element) 返回 true,则 contains() 方法返回 true;否则,返回 false。

默认情况下,Object 类的 equals() 该方法比较了对象的引用。这意味着只有当 o 和 element 指向内存中的同一对象时,o.equals(element) 才会返回 true。

在上述问题描述的代码中,ArrayList 存储的是 Product 试着使用类的对象 String 类型的 name 来调用 contains() 方法。 由于 String 对象和 Product 对象永远不会相等,所以对象永远不会相等 contains() 方法总是回来的 false。

使用循环进行自定义搜索

根据对象的属性(如产品名称) ArrayList 要找到目标对象,需要使用循环遍历 ArrayList,并手动比较每个对象的属性。

以下是如何通过循环和属性比较搜索的示例代码 ArrayList 中的 Product 对象:

import java.util.ArrayList; import java.util.Scanner; class Product { String name; int price; int id; Product(int i, String name, int price) { this.id = i; this.name = name; this.price = price; } } public class Test { public static void main(String[] args) { ArrayList<Product> al = new ArrayList<Product>(); al.add(new Product(1, "Samsung", 10000)); al.add(new Product(2, "Apple", 20000)); al.add(new Product(3, "Nokia", 30000)); al.add(new Product(4, "Sony", 40000)); al.add(new Product(5, "LG", 50000)); System.out.println("Enter the name of the product to search:"); Scanner sc = new Scanner(System.in); String name = sc.nextLine(); boolean found = false; for (Product p : al) { if (p.name.equals(name)) { System.out.println("Product found: " + p.id + " " + p.name + " " + p.price); found = true; break; // 找到第一个匹配项后退出循环 } } if (!found) { System.out.println("Product not found"); } } }

代码解释:

  1. 循环遍历: 使用 for-each 循环遍历 ArrayList 中的每个 Product 对象。
  2. 属性比较: 对于每个 Product 对象 p,使用 p.name.equals(name) 将其 name 属性与用户输入 name 进行比较。
  3. 找到匹配项: 若找匹配的 Product 对象将打印产品信息并将其打印出来 found 标志设置为 true,然后使用 break 语句退出循环。
  4. 没有找到匹配项目: 若循环结束 found 标志仍然为 false,则说明 ArrayList 没有具有指定名称的。 Product 对象,打印 "Product not found"。

重写 equals() 方法 (可选)

另一种方法是重写 Product 类的 equals() 方法是根据产品名称进行比较。 如果重写了 equals() 该方法可直接使用 contains() 方法来查找 Product 对象。

class Product { String name; int price; int id; Product(int i, String name, int price) { this.id = i; this.name = name; this.price = price; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Product product = (Product) obj; return name != null ? name.equals(product.name) : product.name == null; } @Override public int hashCode() { return name != null ? name.hashCode() : 0; } }

注意事项:

  • 如果重写了 equals() 强烈建议同时重写方法 hashCode() 保证方法 equals() 方法和 hashCode() 方法的一致性。 这是因为在 HashMap 和 HashSet 等基于哈希表的集合,hashCode() 该方法用于确定对象的存储位置。 如果 equals() 方法相等但 hashCode() 如果方法不相等,对象可能无法正确存储和检索。

修改后的 Test 类可以使用 contains 但是需要创建临时的方法 Product 对象用于比较:

import java.util.ArrayList; import java.util.Scanner; public class Test { public static void main(String[] args) { ArrayList<Product> al = new ArrayList<Product>(); al.add(new Product(1, "Samsung", 10000)); al.add(new Product(2, "Apple", 20000)); al.add(new Product(3, "Nokia", 30000)); al.add(new Product(4, "Sony", 40000)); al.add(new Product(5, "LG", 50000)); System.out.println("Enter the name of the product to search:"); Scanner sc = new Scanner(System.in); String name = sc.nextLine(); Product searchProduct = new Product(0, name, 0); // 创建临时Product对象 if (al.contains(searchProduct)) { System.out.println("Product found"); } else { System.out.println("Product not found"); } } }

总结在 Java 中,使用 ArrayList 的 contains() 直接找到具有特定属性的对象的方法通常无法得到预期的结果。 这是因为 contains() 默认使用该方法 equals() 比较对象引用的方法。 为了根据对象的属性进行搜索,可以使用循环遍历 ArrayList 并手动比较每个对象的属性。 此外,还可以重写 equals() 为了实现自定义对象的逻辑,需要注意同时重写 hashCode() 方法。根据实际情况选择最合适的搜索方案,以提高代码的可读性和效率。

http://www.cnnetsun.cn/news/1489269.html

相关文章:

  • 电商人必备!用Nano-Banana快速生成商品爆炸图,提升展示效果
  • Efficient Attention实战:在CV任务中如何用1/10显存跑通超大特征图注意力
  • 深入解析智能穿戴设备Android开发工程师职位:技术栈、挑战与面试指南
  • 【华为OD机试真题】亲子游戏 · 最短路径拿最多糖果 (Python /JS)
  • LLM驱动爬虫:利用大语言模型自动解析动态DOM与智能提取非结构化数据
  • Cursor AI 编程助手进阶玩法:如何用OpenAI API Key解锁GPT-4 Turbo的隐藏功能
  • s2-pro开源TTS模型应用:为游戏NPC生成差异化语音台词系统
  • 如何告别抢购焦虑?JD-HAPPY让京东商品自动下单不再是难题
  • 基于AI辅助开发的Chatbot框架实战:从架构设计到性能优化
  • DigVPS 测评 - 蔭雲(YINNET)上新西班牙ISP VPS产品,奉上详评数据,新品七折出售中。
  • OpenClaw技能开发入门:为GLM-4.7-Flash编写自定义模块
  • Python AI用例生成效率黑盒解密:AST静态分析+LLM动态补全双引擎架构(内部培训PPT首次公开)
  • 手把手教你用LMX2594+HMC7043搭建JESD204B时钟树(以2.4GSPS采样为例)
  • ChatGPT收费机制解析与成本优化实战指南
  • fpga实战:基于快马ai快速构建图像边缘检测硬件加速系统
  • AI辅助开发新体验:在快马平台用自然语言指令生成股票数据查询工具
  • 能耗对比:nanobot轻量模型连续运行8小时仅耗电0.5度
  • 三步掌握LosslessCut:高效专业的视频无损剪辑解决方案
  • RMBG-2.0效果可视化分析:热力图展示模型对发丝区域的注意力聚焦强度
  • s2-pro GPU部署优化教程:多模型共享GPU资源时的s2-pro内存隔离配置
  • 百川2-13B-4bits模型微调实战:优化OpenClaw的邮件处理技能
  • 实战复盘:从Wireshark流量中拆解钓鱼邮件的恶意下载链
  • VEEDER ROOT 0125946-020 机械累计计数器
  • OpenClaw实战:星图平台快速搭建Clawdbot私有化Qwen3-VL:30B飞书助手
  • 兼容 MCP 协议,为 OpenClaw 的工具集成能力带来了哪些核心优势?
  • LangChain:RAG开发
  • Qwen3-0.6B-FP8效果对比视频:同一问题在思考/非思考模式下的输出
  • 2026年3月五大GEO优化公司实效横评带你透视业务增长哪家好
  • RTthread消息队列学习
  • springboot基于学生兴趣的学习资源推荐系统 的设计与实现