面向对象中判定重复需重写equals和hashCode,而非依赖String.equals;String.equals仅比较字符串内容,对自定义类须显式比较字段或重写equals以定义相等语义,并确保hashCode同步更新。

用面向对象类配合 String.equals 判定重复输入元素,关键不是直接拿对象本身去比字符串,而是让类明确表达“什么算相等”——这需要重写 equals 方法,并通常同步重写 hashCode。仅靠 String.equals 无法自动作用于自定义类实例,除非你在逻辑中显式调用它来比较某个字符串字段。
明确区分:String.equals 是工具,不是自动规则
String.equals 只能比较两个 String 对象的内容是否相同。如果你有一个类(比如 User),里面有个 name 字段是 String 类型,那你要判断两个 User 是否“因名字重复而视为重复”,就得自己写逻辑:
- 不推荐:
user1 == user2—— 比的是引用,永远错 - 不推荐:
user1.equals(user2)—— 默认继承自Object,仍是引用比较 - 正确方向:
user1.getName().equals(user2.getName())—— 显式用String.equals比字段
让类自己知道怎么算“重复”:重写 equals 和 hashCode
如果“名字相同就认为是重复用户”,那就该在 User 类里定义这个语义:
- 重写
equals(Object o):先判 null 和类型,再强转,最后用Objects.equals(name, other.name)(它会安全处理 null)或直接name != null && name.equals(other.name) - 必须同时重写
hashCode():返回Objects.hash(name),否则放进HashSet或作HashMap键时行为异常 - IDE(如 IntelliJ)可一键生成这两个方法,避免手写疏漏
实际判定重复的常用场景和写法
假设你有一组用户输入,要过滤掉名字重复的:
- 用
Set<User>自动去重:前提是User正确重写了equals和hashCode - 手动检查:遍历已有列表,对每个旧用户调用
newUser.equals(existing) - 只按名字判重(忽略其他字段):可在类里加个专用方法,如
public boolean hasSameName(User other) { return Objects.equals(this.name, other.name); },更清晰表达意图
特别注意 null 和大小写
String.equals 对 null 敏感:调用 null.equals("abc") 会抛 NullPointerException;"abc".equals(null) 安全但返回 false。所以推荐:
- 用
Objects.equals(str1, str2)—— 内部已做 null 判断 - 若需忽略大小写,用
String.equalsIgnoreCase,但要注意它也不接受 null,仍需配合Objects.equals或先判空 - 输入前统一 trim() 空格,避免 "Tom " 和 "Tom" 被当成不同


















