JavaSE中比较器、深拷贝浅拷贝举例详解

 更新时间:2024年07月18日 09:33:43   作者:鸽鸽程序猿  
在Java中一切都可以视为对象,在Java中我们经常使用引用去操作对象,下面这篇文章主要给大家介绍了关于JavaSE中比较器、深拷贝浅拷贝的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

Comparable接口

我们像写一个Dog类,类中包含成员变量年龄和名字。来方便以下讲解。

public class Dog {
    public int age;
    public String name;
    @Override
    public String toString() {
        return "Dog{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

当我们要对自己的自定义类进行直接比较时会发现不能比较,这是因为这些操作符只能比较基本数据类型。

public static void main(String[] args) {
        Dog dog1 = new Dog(6,"xiaohei");
        Dog dog2 = new Dog(7,"xiaobai");
        System.out.println(dog1 > dog2);
    }

单个比较

如果要实现比较功能,我们就要实现Comparable接口,并将其中的compareTo方法重写,在“继承”时将泛型写为当前类:

public class Dog implements Comparable<Dog> {
	private int age;
	public int compareTo(Dog o) {
		return this.age - o.age;
	}
}

在实现后就可以在main函数中调用compareTo方法来比较:

 public static void main(String[] args) {
        Dog dog1 = new Dog(6,"xiaohei");
        Dog dog2 = new Dog(7,"xiaobai");
        System.out.println(dog1 .compareTo(dog2));
    }

从这我们可以看见这个比较方法是通过对象的引用来实现,如果要进行多个对象比较酒不行呢。

多个比较

我们多个比较就可以通过数组来实现,将对象放入数组中进行排序,因为我们实现了Comparable接口,我们调用Arrays.sort()方法就行:

 public static void main(String[] args) {
        Dog dog1 = new Dog(6,"xiaohei");
        Dog dog2 = new Dog(7,"xiaobai");
        Dog dog3 = new Dog(5,"xiaodog");
        Dog dog4 = new Dog(8,"wangcai");
        Dog[] dogs = new Dog[]{dog1,dog2,dog3,dog4};

        Arrays.sort(dogs);

        for (int i = 0; i < dogs.length; i++) {
            System.out.println(dogs[i].toString());

        }
    }

Comparator接口

在实现了Compareable接口后我们就直接将比较方法定死了,不能进行比较条件的修改。如果要解决这个问题就可以使用Comparator接口。
 

我们就在重新写个类来用于Dog类的名字比较,将compare方法重写:

import java.util.Comparator;

public class NameComparator implements Comparator<Dog> {
    @Override
    public int compare(Dog o1, Dog o2) {
        return o1.getName().compareTo(o2.getName());
    }
}

然后再主函数中实例化该对象,再在调用Arrays.sort()的时候将该对象一起传入就可以实现以名字排序,如果是要用年龄排序就按同样方法写出年龄排序的类,然后Arrays.sort()调用的时候传该类就行。

 public static void main(String[] args) {
        Dog dog1 = new Dog(6,"xiaohei");
        Dog dog2 = new Dog(7,"xiaobai");
        Dog dog3 = new Dog(5,"xiaodog");
        Dog dog4 = new Dog(8,"wangcai");
        Dog[] dogs = new Dog[]{dog1,dog2,dog3,dog4};

        NameComparator nameComparator = new NameComparator();
        Arrays.sort(dogs,nameComparator);

        for (int i = 0; i < dogs.length; i++) {
            System.out.println(dogs[i].toString());

        }
    }

Compareable接口,Comparetor接口,equals方法对比

因为所有类都有一个共同父类Object,Object类中有equals方法,我们将该方法重写也可以比较

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Dog dog = (Dog) o;
        return age == dog.age && Objects.equals(name, dog.name);
    }

Compareable接口实现的比较会导致比较方法定死了,Comparetor实现的比较器就可以改变比较的方法,两个都返回int数字,而equals方法只是单纯比较是否相等并且返回值是boolean类型

深拷贝与浅拷贝

拷贝

我们要直接将我们的一个对象给到新对象,像基本数据类型那样用=肯定是不行的,这就需要用到clone方法了:

步骤如下

1.在类中重写clone方法,因为clone方法是Object类的,直接重写就行

2.实现Cloneable接口,该接口是一个空接口,但是必须实现该接口来表示当前类可以克隆。

public class Dog implements Cloneable {
	public String name;
	public int age;
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	public Dog(String name, int age) {
		this.age = age;
		this.name = name;
	}
}

3.在调用克隆的方法还要实现异常throws CloneNotSupportedException

4.调用clone还用向下转型

public static void main(String[] args) 
		throws CloneNotSupportedException {
	Dog dog1 = new Dog("xiaohei",6);
	Dog dog2 = (Dog)dog1.clone();
}

深拷贝浅拷贝区别

二者区别就在与如果当前类还有其他类的对象时,该拷贝是否将该对象一起拷贝。

如果重新开辟了空间拷贝过去了,那就是深拷贝,

如果没有还是指向原来的空间,那就是浅拷贝。

如果要实现深拷贝就在我们类中重写的clone方法中将类中对象也clone,并且类中对象所在类也实现了克隆:

class Price implements Cloneable {
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}
public class Dog implements Cloneable {
	public String name;
	public int age;
	Price price = new Price();
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	public Dog(String name, int age) {
		this.age = age;
		this.name = name;
	}
}

总结 

到此这篇关于JavaSE中比较器、深拷贝浅拷贝的文章就介绍到这了,更多相关JavaSE比较器、深拷贝浅拷贝内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文理解kafka rebalance负载均衡

    一文理解kafka rebalance负载均衡

    这篇文章主要为大家介绍了kafka rebalance负载均衡的深入理解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 实例详解Java调用第三方接口方法

    实例详解Java调用第三方接口方法

    很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接口(短信、天气等),下面这篇文章主要给大家介绍了关于Java调用第三方接口方法的相关资料,需要的朋友可以参考下
    2022-06-06
  • Hibernate的一对一,一对多/多对一关联保存的实现

    Hibernate的一对一,一对多/多对一关联保存的实现

    本文主要介绍了Hibernate的一对一,一对多/多对一关联保存的实现,文中通过示例代码介绍的很详细,感兴趣的可以了解一下
    2021-09-09
  • java导出json格式文件的示例代码

    java导出json格式文件的示例代码

    本篇文章主要介绍了java导出json格式文件的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 将idea中xml文件背景颜色去除的图文教程

    将idea中xml文件背景颜色去除的图文教程

    这篇文章主要介绍了将idea中xml文件背景颜色去除,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • springboot集成mqtt的实践开发

    springboot集成mqtt的实践开发

    本篇文章主要介绍了springboot集成mqtt的实践开发,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • SpringBoot2.0集成WebSocket实现后台向前端推送信息

    SpringBoot2.0集成WebSocket实现后台向前端推送信息

    这篇文章主要介绍了SpringBoot2.0集成WebSocket实现后台向前端推送信息,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • 深入理解Java的接口与抽象类

    深入理解Java的接口与抽象类

    本文主要介绍java 的接口和抽象类,对接口和抽象类进行介绍对比,深入理解,有需要的小伙伴可以参考下
    2016-07-07
  • 浅析springcloud 整合 zipkin-server 内存日志监控

    浅析springcloud 整合 zipkin-server 内存日志监控

    Zipkin是一款开源的分布式实时数据追踪系统(Distributed Tracking System),其主要功能是聚集来自各个异构系统的实时监控数据。这篇文章主要介绍了springcloud 整合 zipkin-server 内存日志监控,需要的朋友可以参考下
    2019-11-11
  • Java控制台实现猜拳游戏

    Java控制台实现猜拳游戏

    这篇文章主要为大家详细介绍了Java控制台实现猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-01-01

最新评论