java list集合中contain()方法詳解--解決我們在使用時多屬性對象實例判斷一直返回false 困擾bug問題

當我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() 方法;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章