目录
Java中的Object类介绍及常用方法和经典接口
Object类介绍
Object类常用方法
toString()方法
equals()方法
clone()方法
经典接口
Comparable接口
Comparator接口
Java中的Object
类介绍及常用方法和经典接口
Object
类介绍
Object
类是Java中所有类的父类,位于Java.lang
包中,默认创建的所有对象都继承自Object
类
Object
类常用方法
toString()
方法
默认情况下,如果直接打印对象名(等于调用对象名.toString()
),则打印出的内容是对象的包名+类名+地址,例如下面的代码:
public class Person {private String name = "zhangsan";private int age = 16;
}// 测试
public class Test {public static void main(String[] args) {Person person = new Person();System.out.println(person);System.out.println(person.toString());}
}输出结果:
com.epsda.advanced.test_Object.Person@154617c
com.epsda.advanced.test_Object.Person@154617c
如果看toString()
方法的源码可以发现toString()
实际实现的方式:
public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
为了打印的是对象的内容而不是对象的地址,需要重写toString()
方法
@Override
public String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';
}
有了重写的toString()
方法,直接打印对象名或者调用toString()
方法就可以直接打印对象中的内容
public class Person {private String name = "zhangsan";private int age = 16;@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}// 测试
public class Test {public static void main(String[] args) {Person person = new Person();System.out.println(person);System.out.println(person.toString());}
}输出结果:
Person{name='zhangsan', age=16}
Person{name='zhangsan', age=16}
equals()
方法
默认情况下,如果使用==
比较基本数据类型,比较的是对应变量中的值,如果使用==
比较引用数据类型,则比较的是对应的地址值,此时如果需要比较引用数据类型中的内容,就需要使用equals()
方法。但是如果是自定义的类类型,没有重写equals()
方法时,比较的结果依旧与==
相同
public class Test {public static void main(String[] args) {Person person1 = new Person();Person person2 = new Person();System.out.println(person1 == person2);System.out.println(person1.equals(person2));}
}输出结果:
false
false
之所以出现这个情况,是因为在自定义的类类型没有重写equals
时会默认调用父类Object中的equals
,该equals
方法比较方式依旧是按照地址比较
public boolean equals(Object obj) {return (this == obj);
}
所以为了不按照地址比较,需要在自定义的类类型中重写equals
方法
需要注意,一般情况下,建议是重写equals方法的同时也需要重写hashCode()
方法,这是为了保持对象一致性,并且确保数据结构(如哈希表实现的集合类HashMap
、HashSet
等)能够正确地工作。下面以仅重写equals
方法为例
@Override
public boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age && Objects.equals(name, person.name);
}
此时再进行比较时,使用equals
方法就会调用重写的equals
方法,从而比较的是对象中的内容
public class Test {public static void main(String[] args) {Person person1 = new Person();Person person2 = new Person();System.out.println(person1 == person2);System.out.println(person1.equals(person2));}
}输出结果:
false
true
clone()
方法
如果想根据一个已经存在的对象创建一个成员相同的同类型对象(彼此地址不同),则可以使用clone()
方法,使用clone
方法前先在对应的类中重写clone
方法,因为父类中的clone
方法属于protected
修饰的方法,在main
方法直接访问是访问不到的
@Override
public Object clone() throws CloneNotSupportedException{return super.clone(); // 调用父类的clone()方法
}// 测试
public class Test {public static void main(String[] args) {Person person = new Person("张三", 20);try {Person person1 = (Person) person.clone();} catch (CloneNotSupportedException e) {System.out.println("无法克隆");}}}
经典接口
Comparable
接口
在Java中基本数据类型的数据(除boolean
类型外)需要比较大小的话,之间使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。
Java给所有引用数据类型的大小比较,指定了一个标准接口,就是java.lang.Comparable
接口:
package java.lang;public interface Comparable{int compareTo(Object obj);
}
使用步骤如下:
第一步:哪个类的对象要比较大小,哪个类就实现java.lang.Comparable
接口,并重写方法,方法体就是要如何比较当前对象和指定的另一个对象的大小
第二步:对象比较大小时,通过对象调用compareTo
方法,根据方法的返回值决定谁大谁小。
this
对象(调用compareTo
方法的对象)减指定对象(传入compareTo()
的参数对象)大于0,返回正整数this
对象(调用compareTo
方法的对象)减指定对象(传入compareTo()
的参数对象)小于0,返回负整数this
对象(调用compareTo
方法的对象)减指定对象(传入compareTo()
的参数对象)等于0,返回零
代码示例:
实现了Comparable
接口的Student
类
public class Student implements Comparable{private String name;private int score;public Student() {}public Student(String name, int score) {this.name = name;this.score = score;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", score=" + score +'}';}/*this:代表students[i]o:代表students[i+1]如果students[i].getScore()-students[i+1].getScore()>0证明数组中的前面一个对象比后面一个对象的分数高*/@Overridepublic int compareTo(Object o) {Student s = (Student) o;return this.getScore()- s.getScore();}
}
测试代码如下:
public class Test01 {public static void main(String[] args) {//创建一个数组Student[] students = new Student[3];Student s1 = new Student("张三", 100);Student s2 = new Student("李四", 60);Student s3 = new Student("王五", 80);students[0] = s1;students[1] = s2;students[2] = s3;for (int j = 0; j<students.length-1;j++){for (int i = 0;i<students.length-1-j;i++){//如果students[i]比students[i+1]大,就排序换位置if (students[i].compareTo(students[i+1])>0){Student temp = students[i];students[i] = students[i+1];students[i+1] = temp;}}}//遍历for (int i = 0; i < students.length; i++) {System.out.println(students[i]);}}
}输出结果如下:
Student{name='李四', score=60}
Student{name='王五', score=80}
Student{name='张三', score=100}
Comparator
接口
当一个类无法被随意修改时,就没有办法再添加其他内容,但是该类又没有实现前面的Comparable接口,此时就需要使用Comparator接口(java.util.Comparator
)自定义比较方式
package java.util;public interface Comparator{int compare (Object o1,Object o2);}
那么我们想要比较某个类的两个对象的大小,怎么做呢?步骤:
第一步:编写一个类,我们称之为比较器类型,实现java.util.Comparator
接口,并重写方法
- 方法体就是你要如何指定的两个对象的大小
第二步:比较大小时,通过比较器类型的对象调用compare()
方法,将要比较大小的两个对象作为compare
方法的实参传入,根据方法的返回值决定谁大谁小。
o1
对象减o2
大于0返回正整数o1
对象减o2
小于0返回负整数o1
对象减o2
等于0返回零
例如
- 固定不变的
Person
代码:
// Person固定假设不能修改增加Comparable接口以及Comparator接口
public class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age && Objects.equals(name, person.name);}@Overridepublic Object clone() throws CloneNotSupportedException{return super.clone();}
}
自定义新的类实现Comparator
接口
// 自定义类实现Comparator类
public class ToCmp implements Comparator {@Overridepublic int compare(Object o1, Object o2) {Person p1 = (Person) o1;Person p2 = (Person) o2;// 年龄升序return p1.getAge() - p2.getAge();}
}
测试代码:
// 测试
public class Test {public static void main(String[] args) {//创建一个数组Person[] persons = new Person[3];Person p1 = new Person("张三", 100);Person p2 = new Person("李四", 60);Person p3 = new Person("王五", 80);persons[0] = p1;persons[1] = p2;persons[2] = p3;// 使用冒泡排序为例for (int j = 0; j<persons.length-1;j++){for (int i = 0;i<persons.length-1-j;i++){//如果Persons[i]比Persons[i+1]大,就排序换位置if (new ToCmp().compare(persons[i],persons[i+1])>0){Person temp = persons[i];persons[i] = persons[i+1];persons[i+1] = temp;}}}//遍历for (int i = 0; i < persons.length; i++) {System.out.println(persons[i]);}}
}输出结果:
Person{name='李四', age=60}
Person{name='王五', age=80}
Person{name='张三', age=100}