Object class and some interfaces built into Java

1. Object class

The Object class is the parent class of all classes

1.1 Methods in the Object class

1.1.1 toString () method

The toString() method in the Object class:

public String toString() {
    
    
    return getClass().getName()+"@"+Integer.toHexString(hashCode());
}

To get the information of a custom type object, you can override the toString method in the custom type (class)

System.out.println(person);//在Person类中没有重写toString方法时,打印的是practice.Person@1b6d3586;在Person类中重写toString方法后,打印的是自定义类型对象的信息(但重写的toString方法要写对)

1.1.2 equals () method

When comparing whether the content in the custom type (class) object is the same, you must override the equals method in the custom type, and the return value of the equals method is true or false. It is recommended that custom types override the equals method (to make the equals method realize the comparison logic you want)
the equals method in the Object class:

public boolean equals(Object obj) {
    
    
    return (this == obj); // 使用引用直接来进行比较,谁调用equals,谁就是this
}

Observe the following code

Person p1 = new Person("ZhangSan", 20);
Person p2 = new Person("ZhangSan", 20);
int a = 10;
int b = 10;
System.out.println(a == b);//打印true
System.out.println(p1 == p2);//打印false
System.out.println(p1.equals(p2));//打印false

The above code p1 and p2 have the same name and age. Here we hope that System.out.println(p1.equals(p2)) will print true.
When the equals method is not rewritten in the Person class, the following two lines of code have no difference

System.out.println(p1 == p2);
System.out.println(p1.equals(p2));

So to rewrite the equals method in the Object class in the Person class, you can manually rewrite it, or use idea to generate it, click Generate and equals() and hashCode()

 @Override
    public boolean equals(Object obj) {
    
    
        if(obj == null) {
    
    //p1可以调用equals方法,说明p1指向的人已经创建好,p2为null不指向任何对象,说明p2指向的人没有被创建好
            return false ;
        }
        if(this == obj) {
    
    
            return true ;
        }
        if(!(obj instanceof Person)) {
    
    //检查obj是否引用了Person类型的对象
            return false ;
        }
        Person person = (Person)obj ;//向下转型,因为obj是父类引用
        return this.name.equals(person.name) && this.age==person.age ;
    }

1.1.3 hashCode () method


It is recommended to override the hashcode method for custom types. You can simply think that the hashcode method returns the address of the object, but this address is the source code of the hashcode method that has been processed:

public native int hashCode();

The hashcode method is modified by native, and the bottom layer is written by C/C++ code, which we cannot see

Person per1 = new Person("yixing", 20) ;
Person per2 = new Person("yixing", 20) ;
System.out.println(per1.hashCode());//打印460141958
System.out.println(per2.hashCode());//打印1163157884

The names and ages of the above codes p1 and p2 are the same. Here we hope that the printed results of System.out.println(per1.hashCode()) and System.out.println(per2.hashCode()) are the same, so the hashCode method in the Object class should be rewritten in the Person class. The following is the rewritten hashCode method generated by idea
:

@Override
public int hashCode() {
    
    
return Objects.hash(name, age);
}

After rewriting the hashCode method in the Object class in the Person class, pass the name and age of p1 and p2 into Objects.hash(name, age) in the rewritten hashCode method. Objects.hash(name, age) logically helps us figure out that this is the same location, and returns the address of the same person

2. Some interfaces built into Java

2.1Comparable interface

(1) To compare the size of objects of a custom type, implement the Comparable interface in this custom type (class), and rewrite the compareTo method in this custom type (class) to realize the comparison logic, because the compareTo method in the Comparable interface has no specific implementation, and the return value of the compareTo method is int. What type is the T of Comparable (such as the Person type), and what type is the parameter of compareTo (such as the Person type), because the generic type of the Comparable source code is written like this

class Person implements Comparable<Person>{
    
    
    public String name ;
    public int age ;
    public Person(String name, int age) {
    
    
        this.age = age ;
        this.name = name ;
    }
    @Override
    public int compareTo(Person o) {
    
    //重写compareTo方法后,compareTo用人的年龄来进行比较
        return this.age - o.age;
    }
}
public class Practice1 {
    
    
    public static void main(String[] args) {
    
    
        Person p1 = new Person("ZhangSan", 15) ;
        Person p2 = new Person("LiSi", 20) ;
        System.out.println(p1.compareTo(p2));//输出结果是-5
    }
}

数组排序Arrays.sort(arrays)底层是将数组的内容拿出来,强制类型转换为Comparable类型再调用compareTo方法(((Comparable)a[runHi++]).compareTo(a[lo])),数组内容是整数时可以用sort直接比较,数组内容是对象的引用时,则要在数组内容的类型(类)中实现comparable接口和重写compareTo方法
comparable接口对类的侵入性比较强,较不灵活
(2)使用比较器,对类的侵入性不强,较灵活,比较器(重新定义一个类,在这个类实现Comparator接口,在这个重新定义的类中重写compare方法,要比较时new一个这个重新定义的类的对象,用这个对象调用重写的compare方法),Comparator的T是什么类型(如Student类型),compare的参数就是什么类型(如Student类型),因为Comparator源码的泛型是这样写的

class AgeComparator implements Comparator<Student>{
    
    
    @Override
    public int compare(Student o1,Student o2){
    
    
        return o1.age-o2.age;
    }
}
class NameComparator implements Comparator<Student> {
    
    
    @Override
    public int compare(Student o1,Student o2){
    
    
        return o1.name.compareTo(o2.name);
    }//o1.name是String类型的引用,String类中实现了Comparable接口和重写了compareTo方法
}

public class Test{
    
    
    public static void main(String[] args) {
    
    
        Person p1 = new Person("ZhangSan", 10);
        Person p2 = new Person("LiSi", 15);
        AgeComparator ageComparator = new AgeComparator();
        System.out.println(ageComparator.compare(p1, p2));
        NameComparator nameComparator = new NameComparator();
        System.out.println(ageComparator.compare(p1, p2));
    }
}

2.2Cloneable interface

(1) There is a clone method in the Object class
The following is a shallow copy:

class Person implements Cloneable{
    
    //克隆接口Cloneable(空接口/标记接口),证明当前类是可以被克隆的
    public int age;
    public Person(int age){
    
    
        this.age = age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException{
    
    //这里重写了Object类的clone方法,Object类的clone方法声明的异常是受查异常/编译时异常,必须是编译时处理
        return super.clone();//clone()在Object类中是protected修饰的(不是public修饰),所以要在Test2类中用person1调用clone()来克隆person1指向的对象,则要在Person类中重写clone()方法,这个重写的clone()方法里面用super调用Object类的clone()方法
    }
}
public class Test2{
    
    
    public static void main (String[] args) throws CloneNotSupportedException{
    
    //声明clone方法会出现的异常
        Person person1 = new Person(10);
        Person person2 = (Person)person1.clone();//向下转型,要强制类型转换,因为clone()方法的返回值类型是Object类型,返回值类型是父类。这里person1调用克隆方法,克隆person1指向的对象
        System.out.println(person1);//以下两个打印的结果相同
        System.out.println(person2);
    }
}

(2) Shallow copy: only clone the object. Deep Copy: Clone an object within an object.
The following is a deep copy:

class Money implements Cloneable{
    
    
    public double money = 10.0;
    @Override
    protected Object clone() throws CloneNotSupportedException {
    
    
        return super.clone();
    }
    @Override
    public String toString() {
    
    
        return "Money{"+"money="+money+'}';
    }
}
class Person implements Cloneable{
    
    
    public int age;
    public Money m;//这里用了组合
    public Person(int age){
    
    
        this.age = age;
        this.m = new Money();
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
    
    
        Person tmp = (Person) super.clone();
        tmp.m = (Money) this.m.clone();//clone()在Money类中虽然是protected修饰,但这里是同一个包下的不同类,所以可以在Person类中通过对象的引用调用Money类的clone()以克隆Money类对象
        return tmp;                    //克隆this.m所指向的内容,谁调用这个方法谁就是this,p1调用了这个方法所以p1是this,克隆p1.m所指向的内容
    }
    @Override
    public String toString() {
    
    
        return "Person{"+"age="+age+",m="+m+'}';
    }
}
class Test2 {
    
    
    public static void main(String[] args) throws CloneNotSupportedException {
    
    
        Person p1 = new Person(10);
        Person p2 = (Person) p1.clone();
        System.out.println(p1);
        System.out.println(p2);
        p2.m.money = 20.0;
        System.out.println(p2);
    }
}

insert image description here
The print result is:
insert image description here
p2.m.money = 20.0 changes the content of money in the m object in the p2 object, indicating that the m object in the p2 object is also cloned.

Guess you like

Origin blog.csdn.net/zhanlongsiqu/article/details/131056622