如何在Java中正确比较列表中配对对象的字符串字段

本文讲解在Java中比较两个列表中对象的字符串属性(如器官名称)时,为何不能使用==而必须用equals(),并通过器官捐献注册系统实例说明修复方法、代码优化与常见陷阱。

本文讲解在Java中比较两个列表中对象的字符串属性(如器官名称)时,为何不能使用`==`而必须用`equals()`,并通过器官捐献注册系统实例说明修复方法、代码优化与常见陷阱。

在Java中,字符串是引用类型,== 比较的是两个变量是否指向内存中的同一对象实例,而非内容是否相等。即使两个 String 对象内容完全相同(例如都为 "heart"),若由不同构造方式生成(如字面量 vs new String()),== 仍可能返回 false。因此,比较字符串内容必须使用 .equals() 方法

回到你的器官捐献系统,问题核心出现在嵌套循环中的这一行:

if(oNeeded.get(k).getOrgan() == oDonated.get(i).getOrgan()) // ❌ 错误!

应修正为:

if("".equals(oNeeded.get(k).getOrgan()) ? 
   "".equals(oDonated.get(i).getOrgan()) : 
   oNeeded.get(k).getOrgan().equals(oDonated.get(i).getOrgan())) // ✅ 安全写法

更简洁且推荐的写法(避免空指针):

if(Objects.equals(oNeeded.get(k).getOrgan(), oDonated.get(i).getOrgan()))

前提:在类顶部添加 import java.util.Objects;

此外,原代码存在多个可优化点:

以下是修复后的关键片段(含健壮性增强):

import java.util.*;
// ... 其他导入

public class OrganDonation {
    // 使用泛型明确类型,避免强制转换
    private static ArrayIndexedList<OrganInfo> oDonated = new ArrayIndexedList<>();
    private static ArrayIndexedList<OrganInfo> oNeeded = new ArrayIndexedList<>();

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        boolean running = true;

        System.out.println(menuOfOptions());
        String input = sc.nextLine().trim();

        while (running) {
            switch (input) {
                case "1":
                    System.out.print("For who? "); String need = sc.nextLine().trim();
                    System.out.print("What organ? "); String organ1 = sc.nextLine().trim();
                    oNeeded.add(new OrganInfo(organ1, need));
                    System.out.println("✓ Recipient registered.\n");
                    break;

                case "2":
                    System.out.print("By who? "); String donor = sc.nextLine().trim();
                    System.out.print("What organ? "); String organ2 = sc.nextLine().trim();
                    oDonated.add(new OrganInfo(organ2, donor));
                    System.out.println("✓ Donor registered.");
                    performMatching(); // 独立匹配方法,清晰可复用
                    break;

                case "3":
                    running = false;
                    System.out.println("Goodbye!");
                    break;

                default:
                    System.out.println("Invalid selection. Please try again.\n");
            }

            if (running) {
                System.out.println(menuOfOptions());
                input = sc.nextLine().trim();
            }
        }
        sc.close();
    }

    // ✅ 核心修复:使用 Objects.equals 安全比较字符串
    private static void performMatching() {
        for (int i = 0; i < oDonated.size(); i++) {
            String donatedOrgan = oDonated.get(i).getOrgan();
            for (int k = 0; k < oNeeded.size(); k++) {
                String neededOrgan = oNeeded.get(k).getOrgan();
                if (Objects.equals(donatedOrgan, neededOrgan)) {
                    System.out.printf("%s's %s was matched to %s%n", 
                        oDonated.get(i).getPerson(),
                        donatedOrgan,
                        oNeeded.get(k).getPerson()
                    );
                    // 可选:移除已匹配项防止重复匹配
                    // oNeeded.remove(k--); break;
                }
            }
        }
    }

    // ... OrganInfo 内部类(保持不变,但建议将字段设为 final)
    public static class OrganInfo {
        private final String _organ;
        private final String _person;

        public OrganInfo(String organ, String person) {
            this._organ = organ == null ? "" : organ.trim();
            this._person = person == null ? "" : person.trim();
        }

        public String getOrgan() { return _organ; }
        public String getPerson() { return _person; }
    }

    public static String menuOfOptions() {
        return """
                1.) Register organ needed.
                2.) Register organ donated.
                3.) Exit.
                ----------------------------
                Select 1, 2 or 3: """;
    }
}

注意事项总结:

掌握字符串比较的本质差异,是写出健壮Java程序的第一道关键门槛——它不只关乎器官匹配,更关乎所有基于内容判断的业务逻辑可靠性。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。