0

0

Java ArrayList中自定义对象属性的查找策略

碧海醫心

碧海醫心

发布时间:2025-09-01 15:59:01

|

996人浏览过

|

来源于php中文网

原创

Java ArrayList中自定义对象属性的查找策略

本教程深入探讨了在Java ArrayList中根据自定义对象(如Product)的特定属性(如名称)进行查找的策略。它解释了为何直接使用 ArrayList.contains(String) 无法实现此功能,并提供了三种有效的实现方案:基于循环迭代的直接查找、利用Java 8 Stream API的函数式查找,以及通过构建 HashMap 实现高效、快速查找的方法,旨在帮助开发者选择最适合其场景的查找机制。

ArrayList.contains() 方法的局限性

java中,arraylist 的 contains(object o) 方法用于判断列表中是否包含指定元素。其底层实现依赖于元素对象的 equals() 方法。具体来说,它会遍历列表中的每个元素 e,如果存在 e.equals(o) 返回 true 的情况,则 contains() 方法返回 true。

当尝试在一个存储 Product 对象的 ArrayList 中搜索一个 String 类型的名称时,例如 al.contains(name),会遇到以下问题:

  1. 类型不匹配:ArrayList 中存储的是 Product 类型的对象,而 contains() 方法传入的是一个 String 对象。在 e.equals(o) 的比较中,一个 Product 对象与一个 String 对象通常不会被认为是相等的,即使它们的某个属性值(如 name)可能相同。
  2. 默认 equals() 行为:如果没有为 Product 类重写 equals() 方法,它将继承 Object 类的 equals() 方法,该方法默认比较的是两个对象的内存地址(即是否是同一个对象实例)。因此,new Product(...) 创建的对象与任何 String 对象都不会相等。

鉴于上述原因,直接使用 ArrayList.contains(String) 无法实现通过产品名称查找 Product 对象的需求,它将始终返回 false。

方案一:迭代遍历查找

最直接且易于理解的方法是遍历 ArrayList 中的每一个 Product 对象,然后检查其 name 属性是否与搜索条件匹配。

示例代码:

小鸽子助手
小鸽子助手

一款集成于WPS/Word的智能写作插件

下载

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

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Optional; // 引入Optional类,虽然此方案未使用,但Stream API会用到

// 定义产品类
class Product {
    int id;
    String name;
    int price;

    public Product(int i, String name, int price) {
        this.id = i;
        this.name = name;
        this.price = price;
    }

    // 重写toString方法,便于打印产品信息
    @Override
    public String toString() {
        return "Product{id=" + id + ", name='" + name + "', price=" + price + "}";
    }
}

public class ProductSearchExample {
    public static void main(String[] args) {
        ArrayList productList = new ArrayList<>();
        productList.add(new Product(1, "Samsung", 10000));
        productList.add(new Product(2, "Apple", 20000));
        productList.add(new Product(3, "Nokia", 30000));
        productList.add(new Product(4, "Sony", 40000));
        productList.add(new Product(5, "LG", 50000));

        System.out.println("当前产品列表:");
        for (Product p : productList) {
            System.out.println(p);
        }

        Scanner scanner = new Scanner(System.in);
        System.out.println("\n请输入要搜索的产品名称:");
        String searchName = scanner.nextLine();

        Product foundProduct = null;
        // 遍历列表查找匹配的产品
        for (Product product : productList) {
            // 使用equalsIgnoreCase进行大小写不敏感的精确匹配
            // 如果需要大小写敏感,使用 product.name.equals(searchName)
            // 如果需要模糊匹配(包含子字符串),使用 product.name.contains(searchName)
            if (product.name.equalsIgnoreCase(searchName)) {
                foundProduct = product;
                break; // 找到第一个匹配项后即可退出循环
            }
        }

        if (foundProduct != null) {
            System.out.println("产品已找到: " + foundProduct);
        } else {
            System.out.println("未找到名称为 '" + searchName + "' 的产品。");
        }
        scanner.close();
    }
}

要点与注意事项:

  • 匹配方式
    • product.name.equals(searchName):进行大小写敏感的精确匹配。
    • product.name.equalsIgnoreCase(searchName):进行大小写不敏感的精确匹配。
    • product.name.contains(searchName):进行大小写敏感的模糊匹配(只要产品名称包含搜索字符串即可)。
  • 性能:此方法的时间复杂度为 O(n),其中 n 是 ArrayList 中元素的数量。对于大型列表,每次搜索都需要遍历整个列表(最坏情况下),这可能会影响性能。
  • 多匹配处理:如果列表中可能存在多个匹配项,上述代码只会返回第一个找到的匹配项。若需查找所有匹配项,则不应使用 break,并将所有匹配项收集到一个新的列表中。

方案二:使用 Java 8 Stream API

Java 8 引入的 Stream API 提供了一种更简洁、更具函数式风格的方式来处理集合数据。通过 filter() 和 findFirst() 方法,可以优雅地实现查找逻辑。

示例代码:

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

import java.util.ArrayList;
import java.util.Optional;
import java.util.Scanner;

// Product 类定义同上

public class ProductSearchStreamExample {
    public static void main(String[] args) {
        ArrayList productList = new ArrayList<>();
        productList.add(new Product(1, "Samsung", 10000));
        productList.add(new Product(2, "Apple", 20000));
        productList.add(new Product(3, "Nokia", 30000));
        productList.add(new Product(4, "Sony", 40000));
        productList.add(new Product(5, "LG", 50000));

        Scanner scanner = new Scanner(System.in);
        System.out.println("\n请输入要搜索的产品名称 (Stream API):");
        String searchName = scanner.nextLine();

        // 使用Stream API查找产品
        Optional foundProductOptional = productList.stream()
            .filter(p -> p.name.equalsIgnoreCase(searchName)) // 过滤出名称匹配的产品
            .findFirst(); // 获取第一个匹配的产品,结果封装在Optional中

        if (foundProductOptional.isPresent()) {
            System.out.println("产品已找到: " + foundProductOptional.get());
        } else {
            System.out.println("未找到名称为 '" + searchName + "' 的产品。");
        }
        scanner.close();
    }
}

要点与注意事项:

  • 简洁性:Stream API 使代码更加紧凑和易读,特别是对于复杂的链式操作。
  • Optional 类:findFirst() 方法返回一个 Optional 对象,它是一个容器对象,可能包含也可能不包含非 null 值。这有助于避免 NullPointerException。
  • 性能:尽管代码更简洁,但其底层机制仍是对集合进行迭代,因此时间复杂度依然是 O(n)。

方案三:利用 HashMap 优化频繁查找

如果需要频繁地根据某个唯一属性(如产品名称或ID)进行查找,并且数据量较大,可以考虑使用 HashMap。HashMap 提供了平均 O(1) 的查找时间复杂度,显著优于 ArrayList 的 O(n)。

示例代码:

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

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

// Product 类定义同上

public class ProductSearchHashMapExample {
    public static void main(String[] args) {
        // 构建一个以产品名称为key,Product对象为value的HashMap
        Map productMap = new HashMap<>();
        // 注意:HashMap的key是大小写敏感的,如果需要忽略大小写,
        // 建议在存储时将key统一转换为小写或大写。
        productMap.put("Samsung", new Product(1, "Samsung", 10000));
        productMap.put("Apple", new Product(2, "Apple", 20000));
        productMap.put("Nokia", new Product(3, "Nokia", 30000));
        productMap.put("Sony", new Product(4, "Sony", 40000));
        productMap.put("LG", new Product(5, "LG", 50000));

        Scanner scanner = new Scanner(System.in);
        System.out.println("\n请输入要搜索的产品名称 (HashMap):");
        String searchName = scanner.nextLine();

        // HashMap的get方法支持O(1)平均时间复杂度查找
        // 如果HashMap的key在存储时已统一处理大小写,这里也需要对searchName进行同样处理
        Product foundProduct = productMap.get(searchName); // 精确匹配

        if (foundProduct != null) {
            System.out.println("产品已找到: " + foundProduct);
        } else {
            System.out.println("未找到名称为 '" + searchName + "' 的产品。");
        }
        scanner.close();
    }
}

要点与注意事项:

  • 查找效率:HashMap 的 get() 方法在平均情况下具有 O(1) 的时间复杂度,查找速度非常快。
  • 空间换时间:使用 HashMap 需要额外的内存来存储键值对,这是一种典型的空间换时间策略。
  • 唯一键:HashMap 适用于通过唯一键(如产品名称、ID等)进行查找的场景。如果产品名称可能重复,HashMap 只能存储最后一个同名产品,或者需要将 value 设计为 List
  • 构建成本:构建 HashMap 本身需要遍历原始数据,其时间复杂度为 O(n)。因此,只有当查找操作远多于构建操作时,使用 HashMap 才能体现出性能优势。
  • 大小写敏感性:HashMap 的键默认是大小写敏感的。如果需要实现大小写不敏感的查找,必须在存入 HashMap 时将键统一转换为小写(或大写),并在查找时对搜索字符串做同样处理。

总结

在Java ArrayList中查找自定义对象的特定属性,不能直接依赖 ArrayList.contains(String)。正确的做法是根据具体需求选择合适的查找策略:

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

832

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

737

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

734

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16925

2023.08.03

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.5万人学习

C# 教程
C# 教程

共94课时 | 6.7万人学习

Java 教程
Java 教程

共578课时 | 46万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号