探究一下ArrayList中contains方法源码

问题导向:最近在项目开发中遇到了比较一个ArrayList<People>对象是否包含某一个people类的实例,我直接调用ArrayList的contains方法结果被老大训了一顿,因为我比较两个对象是都相等其实是比较两个对象的内容是否相同,而不是地址。而直接调用Contains()方法,底层实现其实是调用了Object类的equals()方法,Object类的equals方法底层实使用==比较两个对象地址是否相同,我们要比较类对象的内容是否相同,则需要重写这个类(我这里是People类)的equals方法才可以。

注意:当我们重写某个类的equals方法时候,通常有必要重写该类的hashCode()方法,以满足HashCode方法的常规规定,即对象相等,对象对应的哈希码也应该相等。即:

(1)、若peopleA.equals(peopleB) 为true,则peopleA.hashCode==peopleB.hashCode也应该为true;

(2)、若peopleA.hashCode!=peopleB.hashCode,则peopleA.equals(peopleB)为false

源码解析

ArrayList的contains方法源码调用了indexOf(Object o)方法

 public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

indexOf(Object o)方法

首先判断Object对象是否为空,要是为空就返回当前对象为空的那个位,否则直接调用Object对象的equals方法,进行比较两个对象是否相同。

   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 的equals方法

该方法比较的是两个对象的内存地址是否相同。

 public boolean equals(Object obj) {
        return (this == obj);
    }

应用实例:重写people类

重写equals方法四个步骤

(1)使用==判断参数是否是这个对象的引用

(2)使用instanceof判断参数是否是正确的类型

(3)把参数转换成正确的类型

(4)对于参数的各个属性,是都跟对象的属性值是否相等。

import lombok.Data;

@Data
public class People{
	
	private String name;
	
	private String sex;
	
	private String like;
	
	@Override
	public int hashCode() {
		String uniCode = "name"+"sex"+"like";
		return uniCode.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (obj instanceof People) {
			People  p = (People) obj;
			if (p.getName().equals(this.name) && p.getSex().equals(this.sex) && p.getLike().equals(this.like)) {
				return true;
			}
			return false;
		}
		return false;
	}
	
	

}

猜你喜欢

转载自blog.csdn.net/weixin_42289193/article/details/81626715