package Dec2016;
import java.util.ArrayList;
import java.util.List;
public class Ques1229 {
public static void main(String[] args){
Student stu01 = new Student("001");
Student stu02 = new Student(null);
List<Student> students = new ArrayList<>();
students.add(stu01);
students.add(stu02);
System.out.println("students是否包含001學號:" + students.contains(stu01));
System.out.println("students是否包含null:" + students.contains(stu02));
}
}
class Student {
private String stuId;
public Student(String stuId) { this.stuId = stuId; }
public String getStuId() { return stuId; }
public void setStuId(String stuId) { this.stuId = stuId; }
@Override
public boolean equals(Object obj) {
if (obj instanceof Student) {
Student stu = (Student) obj;
return stuId.equalsIgnoreCase(stu.getStuId().trim()); // 關鍵行
}
return false;
}
}
students是否包含001學號:true
Exception in thread "main" java.lang.NullPointerException
at Student.equals(Ques1229.java:33)
at java.util.ArrayList.indexOf(ArrayList.java:318)
at java.util.ArrayList.contains(ArrayList.java:311)
at Ques1229.main(Ques1229.java:23)
true?students.contains(stu01) 內部呼叫 indexOf 遍歷比較stu01.equals(stu01) → stuId="001" 非 null,正常回傳 truestudents.contains(stu02) 遍歷比較:stu01 比較:stu02.equals(stu01)equals,stuId == null,執行 null.equalsIgnoreCase(...) → NPE@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Student)) return false;
Student other = (Student) obj;
// 雙向 null 安全比較
if (stuId == null && other.stuId == null) return true;
if (stuId == null || other.stuId == null) return false;
return stuId.equalsIgnoreCase(other.stuId.trim());
}
或使用 Objects.equals(stuId, other.stuId) (Java 7+)。
equals 必須處理自欄位與他欄位皆為 null 的情況contains(null) 會直接比較 element == null,不呼叫 equals;但 contains(nonNullRefToNullField) 仍會呼叫 equals@EqualsAndHashCode 或 IDE 自動生成,減少手寫錯誤若 stu02 為 new Student("") 空字串,結果如何?請自行驗證 trim() 後空字串比較行為。