當我list集合爲List<string> list 時候當我們
測試如下代碼返回:
List<String> liststring=new ArrayList<>();
liststring.add("張三");
liststring.add("李四");
String string="李四";
if (liststring.contains(string)) {
System.out.println("true list中包含 string");
}else {
System.out.println("false list中不包含 string");
}
答應結果如下:說明此時contain()可以判斷當前list集合存在已有的string對象
但是當list爲List<User> listUser = new ArrayList<User>();
user對象爲:
public class User {
private String name;
private Integer age;
public User() {
super();
}
public User(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
測試如下代碼:
List<User> listUser = new ArrayList<User>();
User user1 = new User("張三",18);
listUser.add(user1);
User user2 = new User("李四",19);
listUser.add(user2);
User user3 = new User("王五",20);
listUser.add(user3);
User user4 = new User("趙六",21);
listUser.add(user4);
System.out.println(listUser); //創建一個LIst<User>對象數組
User user5 = new User("張三",18); //張三 130 是否在List<User>中 在這個數組中返回true 沒有返回false
if(listUser.contains(user5)){
System.out.println(true);
}else{
System.out.println(false);
}
返回:
明明user5和user1是一樣的,按道理是相等的,但是返回的結果爲false 苦惱了我很久
沒有辦法只能看看list.contain()方法的底層源代碼:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/*
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the lowest index <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
* or -1 if there is no such index.
*/
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;
}
底層就是遍歷list然後依次與所需要判斷的object做equal()方法比較
其實底層就是調用的user5.equal(object);
發現在contains方法會調用 o.equals(elementData[i])方法,其中elementData[i]是個object類的實例。也就是說我在調用list.contains(user)時實際上比較的是user.equals(object) 這當然會返回false。
所有的對象都擁有標識(內存地址)和狀態(數據),同時“==”比較兩個對象的的內存地址,所以說使用Object的equals()方法是比較兩個對象的內存地址是否相等,即若object1.equals(object2)爲true,則表示equals1和equals2實際上是引用同一個對象。雖然有時候Object的equals()方法可以滿足我們一些基本的要求,但是我們必須要清楚我們很大部分時間都是進行兩個對象的比較,這個時候Object的equals()方法就不可以了,實際上JDk中,String、Math等封裝類都對equals()方法進行了重寫。(引用別人的話)
1.當兩個string對象值時:由於生成string對象的優先常量池判斷原則,兩個string對象值相等其所在常量池中地址相同
所以調用equal() 可以返回true
2.當爲非string類型object判斷
不同的對象對應值相同,但是對應的內存地址不同調用equal()返回爲false;
因此要解決我們頭疼的問題:
重寫equal()方法:
則user實體類重寫equal方法如下:
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
User user=(User) obj;
if (this.age.equals(user.age)&&this.name.equals(user.name)) {
return true;
}else {
return false;
}
}else {
return false;
}
}
其中 :instanceof 爲:
instanceof
instanceof是Java中的二元運算符,左邊是對象,右邊是類;當對象是右邊類或子類所創建對象時,返回true;否則,返回false。
這裏說明下:
類的實例包含本身的實例,以及所有直接或間接子類的實例
instanceof左邊顯式聲明的類型與右邊操作元必須是同種類或存在繼承關係,也就是說需要位於同一個繼承樹,否則會編譯錯誤
重新測試判斷:
返回結果爲:
現在大功告成,成功返回true;
所以當以後需要進行對象判斷是需要自定義 重寫object中的equal() 方法;