【Java基础语法】内置接口

前言:

小编紧接着上期抽象类与接口进行了拓展,介绍了一些Java内置有用的接口,希望能够对大家有所帮助。上期博客http://t.csdnimg.cn/0MoDe

1. Comparable 接口

1.1Comparable 接口

在如下代码中:

 public static void main(String[] args) {
        Student[] student=new Student[]{
                new Student("zhangsan",12),
                new Student("lisi",11),
                new Student("wangwu",13),
        };
       
        System.out.println(Arrays.toString(student));
    }
}
class Student {
    public String name;
    public int age;
    public Student(String name,int age){
        this.name=name;
        this.age=age;
    }
    public String toString(){
        return "["+this.name+":"+this.age+"]";
    }
  
}

 我们能进行打印,但是如果我们想进行按年龄进行排序直接进行

Arrays.sort(student);

我们能进行排序吗,显然是不可以的,应为student数组包含了string类。

此时我们就要用到 Comparable接口,让我们的 Student 类实现 Comparable 接口, 并实现其中的 compareTo 方法

代码实例:

class Student2 implements Comparable{
    public String name;
    public int age;
    public Student2(String name,int age){
        this.name=name;
        this.age=age;
    }
    public String toString(){
        return "["+this.name+":"+this.age+"]";
    }
    @Override
    public int compareTo(Object o) {
        Student student=(Student) o;
        return this.age-student.age;
    }
}

实现comparable后要进行重写compareTo方法

在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.然后比较当前对象和参数对象的大小关系。

1.2.comparator接口

在上述代码中存在一个问题,就是无法通过名字进行比较,那么此时我们就要用到comparator接口

代码如下:

class Agecompare implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age- o2.age;
    }
}

理解:设置一个年龄比较类去实现comparaor接口规定为学生类进行比较,重写compare方法,传入比较的学生对象,如果按年龄比较(对象.age),若前者更大,即返回负值。

当然我们也可以规定名字比较

代码如下:

class Namecompare implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }

原理:和上述年龄比较几乎一样,但是在用对像调用时,名字为string类不能够相减,此时string引用类型的compareto方法进行比较。

因为string实现了comparable接口,重写了compareto方法。

内置原码:

1.3总结

两种写法都叫做比较器,但是后者更加灵活,可以根据所需进行编写,而且两者可以共同存在。

2.Clonable 接口和深拷贝

2.1clone的语法

Java 中内置了一些很有用的接口, Clonable 就是其中之一.

例如以下代码

public class test1 {
    public static void main(String[] args) {
        Person person1=new Person(10);
        Person person2=person1.clone();   //代码报错
    }
}
class Person{
    public int age;
    public Person(int age){
        this.age=age;
    }


    @Override
    public String toString() {
        return "Preson="+this.age;
    }
}

代码在clone关键词下面报错

当我们点开object类的clone方法时可以发现clone方法是protect方法 

此时我们要在子类重写

class Person{
    public int age;
    public Person(int age){
        this.age=age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "Preson="+this.age;
    }

 此时克隆的就是person类
Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 "拷贝". 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常.

那么我们就要实现接口;

class Person implements Cloneable

 并且处理异常

但是此时又再次报错,此时就要注意,object是父类,要完成向下转型,那么我们就要强转

Person person2= (Person) person1.clone();

此时我们就不会报错了。

总体代码如下:

public class test1 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1=new Person(10);
        Person person2= (Person) person1.clone();
        System.out.println(person2);
        System.out.println(person1);
    }
}
class Person implements Cloneable{
    public int age;
    public Person(int age){
        this.age=age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "Preson="+this.age;
    }
}

2.2总结处理

处理的异常:

1.object类的clone是protect方法,要实现子类重写

2.解决抛出异常问题

3.实现clone是父类方法,父类给子类要实现向下转型见http://t.csdnimg.cn/kIt7l

4.实现接口cloneable

2.3 浅拷贝

当我们重新设置一个类定义一个变量,并进行引用时,在person2实现更改值,但是输出时person1也会改变,这叫浅拷贝

代码如下:

 public static void main(String[] args) throws CloneNotSupportedException {
        Person person1=new Person(10);
        Person person2= (Person) person1.clone();
        System.out.println(person2.m.money);
        System.out.println(person1.m.money);
        System.out.println("---------------");
        person2.m.money=99.9;
        System.out.println(person2.m.money);
        System.out.println(person1.m.money);


    }
}
class Money{
    public double money=19.9;
}
class Person implements Cloneable{
    public int age;
    public Money m;
    public Person(int age){
        this.age=age;
        this.m=new Money();
    }

我们希望person2输出99.9,person1输出19.9;

但是两者都是99.9;

原因:在实现克隆时,并没有将对象里面的对象进行拷贝

如图:

所以两个还是调用同一个对象里面对象的地址。

2.4深拷贝 

在上述中,我们就要拷贝一个内部对象

所以代码如下:

class Money implements Cloneable{
    public double money=19.9;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

那么此时就要接收克隆出来的地址

protected Object clone() throws CloneNotSupportedException {
        Person temp=(Person) super.clone();

然后克隆内部的对象存在temp里,就有了内部对象的克隆

 protected Object clone() throws CloneNotSupportedException {
        Person temp=(Person) super.clone();
        temp.m=(Money) this.m.clone();
        return temp;
    }

this时person1调用所以就是person1的内部对象进行克隆,最后将temp传给person2实现深拷贝。

2.5结果展示

 3.总结

限于小编能力有限,讲解过程难免有误,希望各位uu提出宝贵意见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值