public static void main(String [] args){
List<String> list=new ArrayList<String>();
list.add("张三");
System.out.println(
list.contains("张三");
}
public boolean contains(Object o) { //o为传入的参数,此时的o为上转型对象
return indexOf(o) >= 0; //调用下面indexOf(Object o)方法并把参数传入
//因为 下面indexOf方法的返回值为int类型 indexOf方法的返回值 大于等于0 便会返回true 否则反之
}
public int indexOf(Object o) { //o为此时方法的形参 参数为上面调用方法时传进来的参数
return indexOfRange(o, 0, size); //调用下面indexOfRange(Object o, int start, int end)方法 size是当前调用contains方法集合的长度 0是因为 集合的下标是从0开始的 o 是由外面传进来的值
}
int indexOfRange(Object o, int start, int end) {
Object[] es = elementData; //把当前调用contains方法集合里面的每个元素放到这个数组里面
if (o == null) { //判断o是否为null 当前 o 是有外部传进来的值 所以肯定不为null
for (int i = start; i < end; i++) {
if (es[i] == null) {
return i;
}
}
} else { //因为上面o不是null 所以便会走else块
for (int i = start; i < end; i++) { //因为上面使用该方法时传进来值 此时start =0 end 时当前集合的长度
if (o.equals(es[i])) { //o代表外面传进来的值 跟es数组中的每一位元素进行equals比较
//此时需要注意 此时出现了多态 因为equals 在object中定义了这个方法在编译时会调用Object中的equals的方法
//但是 在运行时会 会调用Object类的子类中所重写的equals方法 那么这时 谁调用equals方法 便会进入到当前调用类中并且使用equals方法
return i; //如果找到便会返回当前的int类型的下标
}
}
}
return -1; //如果if和else 都不满足 便会返回-1
}
因为我们传进来的Object o是String类型的 那么我们此时便会调用String中重写后的equals方法
public boolean equals(Object anObject) { //注意 注意 注意 重要的事情 说三遍
//equals 是上面这个 indexOfRange(Object o, int start, int end)方法中变量o调用的但是 equals方法中的行参是上面这个 indexOfRange(Object o, int start, int end)方法中的es[]数组 ,数组里面又是储存的当前调用contains方法集合里面的每个元素
if (this == anObject) { //this代表当前 谁调用便会 指向谁 此时this指向调用equals 方法的o anObject 是equals方法的形参 也就是 es[]数组中的每一个元素,进行==地址比较如果地址相等返回true
return true;
}
if (anObject instanceof String) { //判断equals 方法的形参是否为String类型
String aString = (String)anObject; //如果上面判断成功 便会把equals方法的形参转为String类型 并赋值给aString变量
if (!COMPACT_STRINGS || this.coder == aString.coder) { //COMPACT_STRINGS 是String 类中定义的实参 值为false (|| 短路与 满足一个条件即可) COMPACT_STRINGS取反为true 进入
return StringLatin1.equals(value, aString.value); //
// 调用StringLatin1类中的equals方法 里面的两个参数是 你要比较的两个值 并且会把这两个值 拆分为一个一个放入到byte类型的数组中
}
}
return false;
}
public static boolean equals(byte[] value, byte[] other) { //里面两个形参 是上面String类中equals 调用该类中equals 方法传入的值
if (value.length == other.length) { //先比较两个数组的长度 如果长度不同 就不会进入
for (int i = 0; i < value.length; i++) { //循环比较
if (value[i] != other[i]) { //分别比较两个数组中的每一位元素
return false; //只要 有一位不用便会返回false
}
}
return true; //如果两个数组里面所存储的每一位元素都相同 便会返回true
}
return false; //如果没进if判断 便会直接返回false
}
此时我们用Student类 来举例
因为 在上面说明过 equals 在Object中 如果 你调用equals 的类 没有重写 equals 便会调用Object 中的 equals 方法 所以 我们此时要在自定义类中重写equals方法
@Override
public boolean equals(Object anObject) { //equals 是上面这个 indexOfRange(Object o, int start, int end)方法中变量o调用的但是 equals方法中的行参是上面这个 indexOfRange(Object o, int start, int end)方法中的es[]数组 ,数组里面又是储存的当前调用contains方法集合里面的每个元素
if(anObject instanceof Student) { //此时我们以 Student 来举例 判断equals 方法的形参是否为Student类型
Student stu=(Student)anObject; //如果上面判断成功 便会把equals方法的形参转为Student类型 并赋值给stu变量
return this.id.equals(stu.id); ////this代表当前 谁调用便会 指向谁 此时this指向调用equals方法的这个自定义类 那么此时我们用这个类中id 跟 传进来的stu变量里的id 进行比较 比较方式 和上面的讲解的一样
}
原文:https://www.cnblogs.com/xz-kj/p/14757514.html