package com.jd.c;
public class Ct {
public static void main(String[] args) {
String name1="Tom";
String name2="Tom";
System.out.println(name1==name2);//是对象的地址比较。
System.out.println(name1.equals(name2)); //思考:equals代码怎么执行的?
}
}
1,这里的equals的底层代码为:
在equals中式先比较地址是否相等,相等就为True,如果他们地址址不相等(可能是在常量池和堆中建立的),在equals再次会比较这里是从地址中找出对象的一个个的小字符是否相等,相等就返回 True。
/*
public boolean equals(Object anObject) {
//name2传入equals方法——>anObject指向name2对象——>name2为上转型对象
if (this == anObject) {**//如if (o.equals(elementData[i]))这里的this 就是指代o的。**
//因为name1与name2都是采用直接赋值的方式创建的String类型的对象——>==true,都是代表对象的地址。
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
//因为anObject参数指向name2对象——>name2为String类型对象——>所以为下转型。
int n = value.length;
//因为value是全局变量,value为 private final byte[] value;——>实质是this.value.length——>name1 调用 equals ——>this即为name1——this.value.length就是name1的字符有多少个
if (n == anotherString.value.length) {
//anotherString——>指向name2——>anotherString.value.length代表name2有多少个字符——>两个字符串相同,则长度一定相同——>n == anotherString.value.length非常重要
char v1[] = value;//由name1字符组成的数组
char v2[] = anotherString.value;//由name2字符组成的数组
int i = 0;
while (n-- != 0) {//逐个字符比对
if (v1[i] != v2[i])//只要有一个比对失败则两个字符串一定不相同
return false;
i++;
}
return true;
}
}
return false;
}
*/
2,当类型不相同的时候。
String name1="Tom";
Test test= new Test();
System.out.println(name1==test);
//以为javac在编译时已经知道连个类型不相同,所以编译出错
System.out.println(name1.equals(test));//思考:equals代码怎么执行的?点击equals则:
/*
public boolean equals(Object anObject) {//test传入equals方法——>anObject指向test对象——>test为上转型对象
if (this == anObject) {
//因为name1与test地址不同——>==fasle
return true;
}
if (anObject instanceof String) {
//因为anObject参数指向test对象——>test为Test类型对象,不是String类——>anObject instanceof String 输出为false。
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
*/
3,对于contains方法如何执行。
contains中是返回调用indexof的,在indexof中此调用equals方法进行匹配,为true则返回i的值就>=0则就contains为false。
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
ArrayList<String> nameList = new ArrayList<>();//JDK7.0+
nameList.add("Tom");
String name = "Tom";
System.out.println(nameList.contains(name));//思考:contains方法如何执行
}
}
/*
public boolean contains(Object o) {
//name为传入参数——>o指向name所指向的对象——>name对象为上转型对象
return indexOf(o) >= 0;//调用下面indexOf方法
}
public int indexOf(Object o) {
//indexOf方法中o指向contains方法o指向的对象——>indexOf方法o实质指向name对象
if (o == null) { //o不为null——>o != null false
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)//for循环遍历nameList中每一个元素;其中size为全局变量——>this.size——>nameList的元素个数;
if (o.equals(elementData[i]))//o指向的对象与将nameList中遍历出来的每个元素进行对比,对比规则o.equals(elementData[i])——>因为o指向name变量的地址(上转型对象),所以执行时指向的是String类中的equals(因为是string重写了Object类中的equals的方法)。
return i;
}
return -1;
}
*/
4,在对象不存在的情况下。
ArrayList<String> nameList = new ArrayList<>();//JDK7.0+
nameList.add("Tom");
String name = null;
System.out.println(nameList.contains(name));//思考:contains方法如何执行。
/*
public boolean contains(Object o) {//name为传入参数——>o指向name所指向的对象——>name对象为上转型对象
return indexOf(o) >= 0;//调用下面indexOf方法
}
public int indexOf(Object o) {//indexOf方法中o指向contains方法o指向的对象——>indexOf方法o实质指向name对象
if (o == null) {//o为null——>o == null true
for (int i = 0; i < size; i++)//for循环遍历nameList中每一个元素;其中size为全局变量——>this.size——>nameList的元素个数;
if (elementData[i]==null)//o指向的对象与将nameList中遍历出来的每个元素进行对比,对比规则elementData[i]==null
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
*/
ArrayList<String> nameList = new ArrayList<>();//JDK7.0+
nameList.add("Tom");
Test test = new Test();
System.out.println(nameList.contains(test));//思考:contains方法如何执行
/*
public boolean contains(Object o) {//test为传入参数——>o指向test所指向的对象——>test对象为上转型对象
return indexOf(o) >= 0;//调用下面indexOf方法
}
public int indexOf(Object o) {//indexOf方法中o指向contains方法o指向的对象——>indexOf方法o实质指向test对象
if (o == null) {//o不为null——>o != null false
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
//for循环遍历nameList中每一个元素;其中size为全局变量——>this.size——>nameList的元素个数;
if (o.equals(elementData[i]))
//o指向的对象与将nameList中遍历出来的每个元素进行对比,对比规则o.equals(elementData[i])——>因为o指向test变量的地址,所以执行时指向的是Test类中的equals,由于因为Test没有重写Object中euqals方法,所以调用的是继承父类的euqlas,
return i;
}
return -1;
}
*/
}
}
5,contain()中这里面在不同的类型和原来的程序遍历过程。
// ArrayList<String> nameList = new ArrayList<>();//JDK7.0+
// nameList.add("Tom");
// Test test = new Test();
// System.out.println(nameList.contains(test));//思考:contains方法如何执行
/*
public boolean contains(Object o) {//test为传入参数——>o指向test所指向的对象——>test对象为上转型对象
return indexOf(o) >= 0;//调用下面indexOf方法
}
public int indexOf(Object o) {//indexOf方法中o指向contains方法o指向的对象——>indexOf方法o实质指向test对象
if (o == null) {//o不为null——>o == null false
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)//for循环遍历nameList中每一个元素;其中size为全局变量——>this.size——>nameList的元素个数;
if (o.equals(elementData[i]))//o指向的对象与将nameList中遍历出来的每个元素进行对比,对比规则o.equals(elementData[i])——>因为o指向test变量的地址,所以执行时指向的是Test类中的equals,由于因为Test没有重写Object中euqals方法,所以调用的是继承父类的euqlas;如果重写了equals方法,则调用Test类重写后的方法,其中equals参数即为集合中元素
return i;
}
return -1;
}
*/
**ArrayList<Student> studentList = new ArrayList<>();**//JDK7.0,以上版本就不需要用在最后写Student
studentList.add(new Student("110","Tom"));
Student student = new Student("110","Jim");
System.out.println(studentList.contains(student));//思考:contains方法如何执行
/*
public boolean contains(Object o) {//student为传入参数——>o指向student所指向的对象——>student对象为上转型对象
return indexOf(o) >= 0;//调用下面indexOf方法
}
public int indexOf(Object o) {//indexOf方法中o指向contains方法o指向的对象——>indexOf方法o实质指向student对象
if (o == null) {//o不为null——>o == null false
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)//for循环遍历studentList中每一个元素;其中size为全局变量——>this.size——>studentList的元素个数;
if (o.equals(elementData[i]))
/**/o指向的对象与将studentList中遍历出来的每个元素进行对 比,这里的对比是整体类的对比因为在 ArrayList<Student> studentList = new ArrayList<>(); 中范型是Student类型的,在调用studentList.contains(student)时就直接都是整体Student的类型的,student指代的是刚储存的信息,studentList是指代已经储存的信息,在对比规则中o.equals(elementData[i])——>因为o指向student变量的地址,所以执行时指向的是Student类中的equals,由于因为Student没有重写Object中euqals方法,所以调用的是继承父类的euqlas;如果重写了equals方法,则调用Student类重写后的方法,其中equals参数即为集合中元素,其中的elementData[i]是已存在的数据(已经创建过类并初始化过的)。**
return i;//在这里面都是全部进行匹配,因为这都是对象与对象之间的比较所以也就对象内部元素全部的匹对。也可以自己写
}
return -1;
}
*/
}
// @Override
// public boolean equals(Object obj) {
// System.out.println(111);
// return super.equals(obj);
// }
}
6****在建立的一个类中,在这里面是直接重写了equals方法,再调用的时候,是调用时重写后直接对指定的属性进行匹对,而不是原来的全体进行匹配。
public class Student {
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
//this指o,obj中的元素。
//if (o.equals(elementData[i]))中是o在调用equals方法,实则是调用重写后的方法,上转型对象。
Student student = (Student)obj;
return this.id.equals(student.id);//这是比较地址是否相等,相等就为True,如果地址不相等(可能是在常量池和堆中建立的)在equals会比较这里是从地址中找出对象的一个个的小字符是否相等,相等就返回 True
}
}
前面已经重写了equals的方法了,在建立学生信息删除时候,已经在原来的类中写好了构造方法了只对ID赋值,在调用的remove()方法中也同样调用了equals方法,也如contain()的方法一样,这样的匹配会更加的精准。