前言:
小编紧接着上期抽象类与接口进行了拓展,介绍了一些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提出宝贵意见。
标签:clone,内置,Java,int,age,接口,Person,Student,public From: https://blog.csdn.net/GGBond778/article/details/140638478