問題引子:
ist<Student> students=new ArrayList<Student>(); students.add(new Student("20160800612")); System.out.println(students.contains(new Student("20160800612")))
返回FALSE
Student stu=new Student("123"); students.add(stu); System.out.println(students.contains(stu));
返回TRUE
對於以上代碼,相信很多人有問題,這種不能靠主管想象力的,,,,我們還是來看后台代碼靠譜
按住ctrl鍵點擊contains進入List.class是一個接口,其中有的一個抽象方法 boolean contains(Object o);
他實際上調用的contains方法是ArrayList類中重新的contains方法
public boolean contains(Object o) { return indexOf(o) >= 0; }
按住ctrl鍵點擊indexOf進入ArrayList類中indexOf方法
public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; }
我們看到Object o會調用equals方法,但是Student中並沒有重新equals方法,所以最后調用的事Object 中的equals方法
public boolean equals(Object obj) { return (this == obj); }
很明顯,this==obj比較的事地址,所以兩個new的對象地址肯定不是一樣的,所以返回false
懂了吧~~~~~~~~~~~~~
所以還是多分析分析后台代碼,更加清楚明白啦
怎么解決這個問題呢,就是在Student類中重寫這個 equals方法,比較的時候去比較id 但是注意重寫時參數是Object 我們需要下轉型,這個時候要判斷Object是否為Student
@Override public boolean equals(Object obj) { if(obj instanceof Student) return ((Student)obj).id.equals(this.id); return false; }
OK!!!!!!